1 /*
2  * Copyright 2002-2009 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.aop.aspectj.annotation;
18 
19 import org.springframework.beans.factory.BeanFactory;
20 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
21 import org.springframework.core.Ordered;
22 import org.springframework.core.annotation.Order;
23 import org.springframework.util.ClassUtils;
24 
25 /**
26  * {@link org.springframework.aop.aspectj.AspectInstanceFactory} implementation
27  * backed by a Spring {@link org.springframework.beans.factory.BeanFactory}.
28  *
29  * <p>Note that this may instantiate multiple times if using a prototype,
30  * which probably won't give the semantics you expect.
31  * Use a {@link LazySingletonAspectInstanceFactoryDecorator}
32  * to wrap this to ensure only one new aspect comes back.
33  *
34  * @author Rod Johnson
35  * @author Juergen Hoeller
36  * @since 2.0
37  * @see org.springframework.beans.factory.BeanFactory
38  * @see LazySingletonAspectInstanceFactoryDecorator
39  */
40 public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
41 
42 	private final BeanFactory beanFactory;
43 
44 	private final String name;
45 
46 	private final AspectMetadata aspectMetadata;
47 
48 
49 	/**
50 	 * Create a BeanFactoryAspectInstanceFactory. AspectJ will be called to
51 	 * introspect to create AJType metadata using the type returned for the
52 	 * given bean name from the BeanFactory.
53 	 * @param beanFactory BeanFactory to obtain instance(s) from
54 	 * @param name name of the bean
55 	 */
BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name)56 	public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name) {
57 		this(beanFactory, name, beanFactory.getType(name));
58 	}
59 
60 	/**
61 	 * Create a BeanFactoryAspectInstanceFactory, providing a type that AspectJ should
62 	 * introspect to create AJType metadata. Use if the BeanFactory may consider the type
63 	 * to be a subclass (as when using CGLIB), and the information should relate to a superclass.
64 	 * @param beanFactory BeanFactory to obtain instance(s) from
65 	 * @param name the name of the bean
66 	 * @param type the type that should be introspected by AspectJ
67 	 */
BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class type)68 	public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class type) {
69 		this.beanFactory = beanFactory;
70 		this.name = name;
71 		this.aspectMetadata = new AspectMetadata(type, name);
72 	}
73 
74 
getAspectInstance()75 	public Object getAspectInstance() {
76 		return this.beanFactory.getBean(this.name);
77 	}
78 
getAspectClassLoader()79 	public ClassLoader getAspectClassLoader() {
80 		if (this.beanFactory instanceof ConfigurableBeanFactory) {
81 			return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
82 		}
83 		else {
84 			return ClassUtils.getDefaultClassLoader();
85 		}
86 	}
87 
getAspectMetadata()88 	public AspectMetadata getAspectMetadata() {
89 		return this.aspectMetadata;
90 	}
91 
92 	/**
93 	 * Determine the order for this factory's target aspect, either
94 	 * an instance-specific order expressed through implementing the
95 	 * {@link org.springframework.core.Ordered} interface (only
96 	 * checked for singleton beans), or an order expressed through the
97 	 * {@link org.springframework.core.annotation.Order} annotation
98 	 * at the class level.
99 	 * @see org.springframework.core.Ordered
100 	 * @see org.springframework.core.annotation.Order
101 	 */
getOrder()102 	public int getOrder() {
103 		Class<?> type = this.beanFactory.getType(this.name);
104 		if (type != null) {
105 			if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
106 				return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
107 			}
108 			Order order = type.getAnnotation(Order.class);
109 			if (order != null) {
110 				return order.value();
111 			}
112 		}
113 		return Ordered.LOWEST_PRECEDENCE;
114 	}
115 
116 
117 	@Override
toString()118 	public String toString() {
119 		return getClass().getSimpleName() + ": bean name '" + this.name + "'";
120 	}
121 
122 }
123