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