View Javadoc

1   /*
2    * Copyright 2006-2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.osgi.service.importer.support;
18  
19  import org.springframework.beans.factory.FactoryBean;
20  import org.springframework.beans.factory.FactoryBeanNotInitializedException;
21  import org.springframework.beans.factory.SmartFactoryBean;
22  import org.springframework.osgi.context.internal.classloader.AopClassLoaderFactory;
23  
24  /**
25   * Package protected class that provides the common aop infrastructure
26   * functionality for OSGi service importers. Provides most of the constructs
27   * required for assembling the service proxies, leaving subclasses to decide on
28   * the service cardinality (one service or multiple) and proxy weaving.
29   * 
30   * 
31   * @author Costin Leau
32   * @author Adrian Colyer
33   * @author Hal Hildebrand
34   * 
35   */
36  abstract class AbstractServiceImporterProxyFactoryBean extends AbstractOsgiServiceImportFactoryBean implements
37  		SmartFactoryBean {
38  
39  	private boolean initialized = false;
40  
41  	private Object proxy;
42  
43  	/** aop classloader */
44  	private ClassLoader aopClassLoader;
45  
46  
47  	public void afterPropertiesSet() {
48  		super.afterPropertiesSet();
49  		initialized = true;
50  	}
51  
52  	public void destroy() throws Exception {
53  		Runnable callback = getProxyDestructionCallback();
54  		try {
55  			if (callback != null) {
56  				callback.run();
57  			}
58  		}
59  		finally {
60  			proxy = null;
61  
62  		}
63  	}
64  
65  	/**
66  	 * Returns a managed object for accessing OSGi service(s).
67  	 * 
68  	 * @return managed OSGi service(s)
69  	 */
70  	public Object getObject() {
71  		if (!initialized)
72  			throw new FactoryBeanNotInitializedException();
73  
74  		if (proxy == null) {
75  			proxy = createProxy();
76  		}
77  
78  		return proxy;
79  	}
80  
81  	/**
82  	 * {@inheritDoc}
83  	 * 
84  	 * The object managed by this factory is a singleton.
85  	 * 
86  	 * @return true (i.e. the FactoryBean returns singletons)
87  	 */
88  	public boolean isSingleton() {
89  		return true;
90  	}
91  
92  	/**
93  	 * {@inheritDoc}
94  	 * 
95  	 * The object created by this factory bean is eagerly initialized.
96  	 * 
97  	 * @return true (this factory bean should be eagerly initialized)
98  	 */
99  	public boolean isEagerInit() {
100 		return true;
101 	}
102 
103 	/**
104 	 * {@inheritDoc} The object returned by this FactoryBean is a not a
105 	 * prototype.
106 	 * 
107 	 * @return false (the managed object is not a prototype)
108 	 */
109 	public boolean isPrototype() {
110 		return false;
111 	}
112 
113 	/**
114 	 * Creates the proxy tracking the matching OSGi services. This method is
115 	 * guaranteed to be called only once, normally during initialization.
116 	 * 
117 	 * @return OSGi service tracking proxy.
118 	 * @see #getProxyDestructionCallback()
119 	 */
120 	abstract Object createProxy();
121 
122 	/**
123 	 * Returns the destruction callback associated with the proxy created by
124 	 * this object. The callback is called once, during the destruction process
125 	 * of the {@link FactoryBean}.
126 	 * 
127 	 * @return destruction callback for the service proxy.
128 	 * @see #createProxy()
129 	 */
130 	abstract Runnable getProxyDestructionCallback();
131 
132 	/**
133 	 * Returns the class loader used for AOP weaving
134 	 * 
135 	 * @return the classloader used for weaving
136 	 */
137 	ClassLoader getAopClassLoader() {
138 		return aopClassLoader;
139 	}
140 
141 	/**
142 	 * {@inheritDoc}
143 	 * 
144 	 * The class will automatically chain this classloader with the AOP
145 	 * infrastructure classes (even if these are not visible to the user) so
146 	 * that the proxy creation can be completed successfully.
147 	 */
148 	public void setBeanClassLoader(ClassLoader classLoader) {
149 		super.setBeanClassLoader(classLoader);
150 		this.aopClassLoader = AopClassLoaderFactory.getAopClassLoaderFor(classLoader);
151 	}
152 }