??? profile是Spring3.1提供的一个新的配置项,在下面的测试示例中,又有使用了多种AOP配置方式,为了将各种配置方式进行对比在此使用了profile.在测试用例中通过使用@ActiveProfiles("four")注解指定profile的值。
? Aop?是Spring?框架的核心功能之一。
??? Advice?通知时定义在该连接点做什么,为切面增强提供织入接口。Advice是AOP联盟定义的一个接口,在Spring中对其进行了扩展,提供了更为具体的接口如:BeforeAdvice,AfterAdvice,ThrwosAdvice等。
?
public interface MethodBeforeAdvice extends BeforeAdvice { /** *在指定方法调用前执行该回调方法 */ void before(Method method, Object[] args, Object target) throws Throwable; }
?Pointcut切点,决定advice通知应该作用于哪个连接点,也就是说Pointcut来定义需要增强方法的集合,这些集合的选取可以按照一定的规则来完成。Spring中默认提供了JdkRegexpMethodPointcut,基于正则表达式去匹配增强方法。
???Advisor通知器,在完成对既定目标的增强切面的设计(advice)和关注点的设计(Pointcut)以后,还需要将Advice和Pointcut两者关联起来,完成这个工作的就是Advisor.?通过Advisor,可以定义在哪个关注点上使用哪个通知。在Spring?中默认提供了一个DefultPointcutAdvisor,并以此为例完成AOP demo.
public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable { private Pointcut pointcut = Pointcut.TRUE; public DefaultPointcutAdvisor() { } public DefaultPointcutAdvisor(Advice advice) { this(Pointcut.TRUE, advice); } public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) { this.pointcut = pointcut; setAdvice(advice); } //设置切点 public void setPointcut(Pointcut pointcut) { this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE); } public Pointcut getPointcut() { return this.pointcut; } @Override public String toString() { return getClass().getName() + ": pointcut [" + getPointcut() + "]; advice [" + getAdvice() + "]"; } } public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable { //优先级 private Integer order; public void setOrder(int order) { this.order = order; } public int getOrder() { if (this.order != null) { return this.order; } Advice advice = getAdvice(); if (advice instanceof Ordered) { return ((Ordered) advice).getOrder(); } return Ordered.LOWEST_PRECEDENCE; } public boolean isPerInstance() { return true; } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof PointcutAdvisor)) { return false; } PointcutAdvisor otherAdvisor = (PointcutAdvisor) other; return (ObjectUtils.nullSafeEquals(getAdvice(), otherAdvisor.getAdvice()) && ObjectUtils.nullSafeEquals(getPointcut(), otherAdvisor.getPointcut())); } @Override public int hashCode() { return PointcutAdvisor.class.hashCode(); } } public abstract class AbstractGenericPointcutAdvisor extends AbstractPointcutAdvisor { private Advice advice; public void setAdvice(Advice advice) { this.advice = advice; } public Advice getAdvice() { return this.advice; } @Override public String toString() { return getClass().getName() + ": advice [" + getAdvice() + "]"; } }
?在Spring AOP?使用中可以通过ProxyFactoryBean来配置目标对象和切面的行为。在ProxyFactoryBean中通过interceptorNames属性来配置已经定义好的advisor.虽然名字是interceptor实际上就是配置advisor.在ProxyFactoryBean中需要为target目标对象生成一个动态代理对象proxy,从而为AOP切面的编织做好准备工作。
?
public class ProxyFactoryBean extends ProxyCreatorSupport implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware { /** * This suffix in a value in an interceptor list indicates to expand globals. */ public static final String GLOBAL_SUFFIX = "*"; protected final Log logger = LogFactory.getLog(getClass()); private String[] interceptorNames; private String targetName; private boolean autodetectInterfaces = true; private boolean singleton = true; private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance(); private boolean freezeProxy = false; private transient ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader(); private transient boolean classLoaderConfigured = false; private transient BeanFactory beanFactory; /** Whether the advisor chain has already been initialized */ private boolean advisorChainInitialized = false; /** If this is a singleton, the cached singleton proxy instance */ private Object singletonInstance; public void setProxyInterfaces(Class[] proxyInterfaces) throws ClassNotFoundException { setInterfaces(proxyInterfaces); } public void setInterceptorNames(String[] interceptorNames) { this.interceptorNames = interceptorNames; } public void setTargetName(String targetName) { this.targetName = targetName; } public void setAutodetectInterfaces(boolean autodetectInterfaces) { this.autodetectInterfaces = autodetectInterfaces; } public void setSingleton(boolean singleton) { this.singleton = singleton; } public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) { this.advisorAdapterRegistry = advisorAdapterRegistry; } @Override public void setFrozen(boolean frozen) { this.freezeProxy = frozen; } public void setProxyClassLoader(ClassLoader classLoader) { this.proxyClassLoader = classLoader; this.classLoaderConfigured = (classLoader != null); } public void setBeanClassLoader(ClassLoader classLoader) { if (!this.classLoaderConfigured) { this.proxyClassLoader = classLoader; } } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; checkInterceptorNames(); } /** * 返回一个代理对象。当客户端从这个FactoryBean中获取bean时调用该接口 */ public Object getObject() throws BeansException { //初始化通知器链 initializeAdvisorChain(); //如果是单例的则返回一个单例实例 if (isSingleton()) { return getSingletonInstance(); } else { if (this.targetName == null) { logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " + "Enable prototype proxies by setting the ‘targetName‘ property."); } //返回以prototype实例 return newPrototypeInstance(); } } /** * 返回代理对象类型 */ public Class<?> getObjectType() { synchronized (this) { if (this.singletonInstance != null) { return this.singletonInstance.getClass(); } } Class[] ifcs = getProxiedInterfaces(); if (ifcs.length == 1) { return ifcs[0]; } else if (ifcs.length > 1) { return createCompositeInterface(ifcs); } else if (this.targetName != null && this.beanFactory != null) { return this.beanFactory.getType(this.targetName); } else { return getTargetClass(); } } public boolean isSingleton() { return this.singleton; } protected Class createCompositeInterface(Class[] interfaces) { return ClassUtils.createCompositeInterface(interfaces, this.proxyClassLoader); } /** * 返回一个单例的代理对象 */ private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // 根据AOP框架来判断需要代理的接口 Class targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } //设置代理接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // 初始化一个单例 super.setFrozen(this.freezeProxy); this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; } /** * 创建一个新的prototype 代理对象 */ private synchronized Object newPrototypeInstance() { if (logger.isTraceEnabled()) { logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this); } ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory()); TargetSource targetSource = freshTargetSource(); copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain()); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { copy.setInterfaces( ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader)); } copy.setFrozen(this.freezeProxy); if (logger.isTraceEnabled()) { logger.trace("Using ProxyCreatorSupport copy: " + copy); } return getProxy(copy.createAopProxy()); } protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.proxyClassLoader); } /** * 检查interceptorNames列表中最后一个元素是否是目标对象名称。 */ private void checkInterceptorNames() { if (!ObjectUtils.isEmpty(this.interceptorNames)) { String finalName = this.interceptorNames[this.interceptorNames.length - 1]; if (this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) { // The last name in the chain may be an Advisor/Advice or a target/TargetSource. // Unfortunately we don‘t know; we must look at type of the bean. if (!finalName.endsWith(GLOBAL_SUFFIX) && !isNamedBeanAnAdvisorOrAdvice(finalName)) { // The target isn‘t an interceptor. this.targetName = finalName; if (logger.isDebugEnabled()) { logger.debug("Bean with name ‘" + finalName + "‘ concluding interceptor chain " + "is not an advisor class: treating it as a target or TargetSource"); } String[] newNames = new String[this.interceptorNames.length - 1]; System.arraycopy(this.interceptorNames, 0, newNames, 0, newNames.length); this.interceptorNames = newNames; } } } } private boolean isNamedBeanAnAdvisorOrAdvice(String beanName) { Class namedBeanClass = this.beanFactory.getType(beanName); if (namedBeanClass != null) { return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass)); } // Treat it as an target bean if we can‘t tell. if (logger.isDebugEnabled()) { logger.debug("Could not determine type of bean with name ‘" + beanName + "‘ - assuming it is neither an Advisor nor an Advice"); } return false; } /** * 创建一个通知器链 */ private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException { //如果通知器链已经初始化则直接返回 if (this.advisorChainInitialized) { return; } // 如果没有配置过通知器则抛出异常 if (!ObjectUtils.isEmpty(this.interceptorNames)) { if (this.beanFactory == null) { throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " + "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames)); } //如果没有指定targetSource则最后一个通知器不能是全局通知器 if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) && this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) { throw new AopConfigException("Target required after globals"); } // 通过通知器名称获取通知器对象 for (String name : this.interceptorNames) { if (logger.isTraceEnabled()) { logger.trace("Configuring advisor or advice ‘" + name + "‘"); } //如果通知器名称是以*结尾的且beanFactory不适ListableBeanFactory则抛出异常,否则添加全局通知器 if (name.endsWith(GLOBAL_SUFFIX)) { if (!(this.beanFactory instanceof ListableBeanFactory)) { throw new AopConfigException( "Can only use global advisors or interceptors with a ListableBeanFactory"); } addGlobalAdvisor((ListableBeanFactory) this.beanFactory, name.substring(0, name.length() - GLOBAL_SUFFIX.length())); } else { //非全局通知器 Object advice; //如果该beanFactory是单例的或者是通知器是单例的则从beanFactory中获取单例的通知器,否则获取一个原型的通知器 if (this.singleton || this.beanFactory.isSingleton(name)) { advice = this.beanFactory.getBean(name); } else { advice = new PrototypePlaceholderAdvisor(name); } //添加到通知器链中 addAdvisorOnChainCreation(advice, name); } } } //设置通知器初始化完成标识 this.advisorChainInitialized = true; } /** * 返回通知器列表 */ private List<Advisor> freshAdvisorChain() { Advisor[] advisors = getAdvisors(); List<Advisor> freshAdvisors = new ArrayList<Advisor>(advisors.length); for (Advisor advisor : advisors) { if (advisor instanceof PrototypePlaceholderAdvisor) { PrototypePlaceholderAdvisor pa = (PrototypePlaceholderAdvisor) advisor; if (logger.isDebugEnabled()) { logger.debug("Refreshing bean named ‘" + pa.getBeanName() + "‘"); } // Replace the placeholder with a fresh prototype instance resulting // from a getBean() lookup if (this.beanFactory == null) { throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " + "- cannot resolve prototype advisor ‘" + pa.getBeanName() + "‘"); } Object bean = this.beanFactory.getBean(pa.getBeanName()); Advisor refreshedAdvisor = namedBeanToAdvisor(bean); freshAdvisors.add(refreshedAdvisor); } else { // Add the shared instance. freshAdvisors.add(advisor); } } return freshAdvisors; } /** * 添加所有的通知器和切点 */ private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) { //获取beanFactory中定义的所有的通知器 String[] globalAdvisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class); // 获取beanFactory中定义的所有的Interceptor String[] globalInterceptorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class); List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length); Map<Object, String> names = new HashMap<Object, String>(beans.size()); //遍历所有的通知器 for (String name : globalAdvisorNames) { Object bean = beanFactory.getBean(name); beans.add(bean); names.put(bean, name); } //遍历所有拦截器 for (String name : globalInterceptorNames) { Object bean = beanFactory.getBean(name); beans.add(bean); names.put(bean, name); } //排序 OrderComparator.sort(beans); //遍历所有,如果拦截器或通知器是以指定的前缀开始的则添加到通知器中 for (Object bean : beans) { String name = names.get(bean); if (name.startsWith(prefix)) { addAdvisorOnChainCreation(bean, name); } } } /** * 添加一个通知器 */ private void addAdvisorOnChainCreation(Object next, String name) { //转换为一个通知器 Advisor advisor = namedBeanToAdvisor(next); if (logger.isTraceEnabled()) { logger.trace("Adding advisor with name ‘" + name + "‘"); } //添加通知器 addAdvisor(advisor); } /** * 在创建一个代理对象时返回一个TargetSource */ private TargetSource freshTargetSource() { if (this.targetName == null) { if (logger.isTraceEnabled()) { logger.trace("Not refreshing target: Bean name not specified in ‘interceptorNames‘."); } return this.targetSource; } else { if (this.beanFactory == null) { throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " + "- cannot resolve target with name ‘" + this.targetName + "‘"); } if (logger.isDebugEnabled()) { logger.debug("Refreshing target with name ‘" + this.targetName + "‘"); } Object target = this.beanFactory.getBean(this.targetName); return (target instanceof TargetSource ? (TargetSource) target : new SingletonTargetSource(target)); } } /** * 对给定的对象转换为一个通知器 */ private Advisor namedBeanToAdvisor(Object next) { try { return this.advisorAdapterRegistry.wrap(next); } catch (UnknownAdviceTypeException ex) { throw new AopConfigException("Unknown advisor type " + next.getClass() + "; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," + "which may also be target or TargetSource", ex); } } @Override protected void adviceChanged() { super.adviceChanged(); if (this.singleton) { logger.debug("Advice has changed; recaching singleton instance"); synchronized (this) { this.singletonInstance = null; } } } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { // Rely on default serialization; just initialize state after deserialization. ois.defaultReadObject(); // Initialize transient fields. this.proxyClassLoader = ClassUtils.getDefaultClassLoader(); } private static class PrototypePlaceholderAdvisor implements Advisor, Serializable { private final String beanName; private final String message; public PrototypePlaceholderAdvisor(String beanName) { this.beanName = beanName; this.message = "Placeholder for prototype Advisor/Advice with bean name ‘" + beanName + "‘"; } public String getBeanName() { return beanName; } public Advice getAdvice() { throw new UnsupportedOperationException("Cannot invoke methods: " + this.message); } public boolean isPerInstance() { throw new UnsupportedOperationException("Cannot invoke methods: " + this.message); } @Override public String toString() { return this.message; } } }
?ProxyCreatorSupport
?
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
?DefaultAopProxyFactory,这里是实际创建代理的地方
?
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface()) { return new JdkDynamicAopProxy(config); } if (!cglibAvailable) { throw new AopConfigException( "Cannot proxy target class because CGLIB2 is not available. " + "Add CGLIB to the class path or specify proxy interfaces."); } return CglibProxyFactory.createCglibProxy(config); } else { return new JdkDynamicAopProxy(config); } }
?
?
?
?
?
?
?
?
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd " default-autowire="byType"> <!-- 定义一个通知 --> <bean id="authInterceptor" class="com.cathy.demo.spring.aop.AuthInterceptor" /> <!-- 定义切点,匹配所有方法 --> <bean id="authPoint" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*" /> </bean> <!-- 定义通知 器 --> <bean id="authAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut" ref="authPoint" /> <property name="advice" ref="authInterceptor" /> </bean> <bean id="aopDemo" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="com.cathy.demo.spring.aop.AopDemo" /> </property> <property name="interceptorNames" value="authAdvisor" /> <property name="proxyInterfaces" value="com.cathy.demo.spring.aop.Say" /> </bean> </beans>
?
/** * 方法调用前的权限拦截器 * @author zhangwei_david * @version $Id: AuthInterceptor.java, v 0.1 2015年7月10日 上午10:18:12 zhangwei_david Exp $ */ public class AuthInterceptor implements MethodBeforeAdvice { /** * @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method, java.lang.Object[], java.lang.Object) */ public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("调用 方法:" + method); } }
?
/** * * @author zhangwei_david * @version $Id: AopDemo.java, v 0.1 2015年7月10日 上午10:21:20 zhangwei_david Exp $ */ public class AopDemo implements Say { public void say() { System.out.println("hello"); } }
?
/** * * * @author zhangwei_david * @version $Id: SpringAopTest.java, v 0.1 2015年7月10日 上午10:51:16 zhangwei_david Exp $ */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath*:META-INF/spring/aop-beans.xml") public class SpringAopTest { @Autowired private Say aopDemo; @Test public void test() { aopDemo.say(); } }
?
2015-07-10 10:40:14 [ main:375 ] - [ INFO ] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@190a65e: defining beans [authInterceptor,authPoint,authAdvisor,aopDemo,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy 调用 方法:public abstract void com.cathy.demo.spring.aop.Say.say() hello 2015-07-10 10:40:14 [ Thread-0:494 ] - [ INFO ] Closing org.springframework.context.support.GenericApplicationContext@ee68d8: startup date [Fri Jul 10 10:40:14 CST 2015]; root of context hierarchy 2015-07-10 10:40:14 [ Thread-0:494 ] - [ INFO ] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@190a65e: defining beans [authInterceptor,authPoint,authAdvisor,aopDemo,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
?
其他的配置方式如下:
/** * 方法调用前的权限拦截器 * @author zhangwei_david * @version $Id: AuthInterceptor.java, v 0.1 2015年7月10日 上午10:18:12 zhangwei_david Exp $ */ @Component @Aspect public class BeforeInterceptor { @Before("execution(* *.*(..))") public void before(JoinPoint joinPoint) throws Throwable { System.out.println("before [target" + joinPoint.getTarget() + ", signature:" + joinPoint.getSignature()); } }
?
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd " default-autowire="byType"> <!-- 使用ProxyFactoryBean 实现aop --> <beans profile="one"> <!-- 定义一个通知 --> <bean id="authInterceptor" class="com.cathy.demo.spring.aop.AuthInterceptor" /> <!-- 定义切点,匹配所有方法 --> <bean id="authPoint" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*" /> </bean> <!-- 定义通知 器 --> <bean id="authAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut" ref="authPoint" /> <property name="advice" ref="authInterceptor" /> </bean> <bean id="aopDemo" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="com.cathy.demo.spring.aop.AopDemo" /> </property> <property name="interceptorNames" value="auth*" /> </bean> </beans> <!-- 优化配置,使用DefaultAdvisorAutoProxyCreator --> <beans profile="two"> <!-- 定义一个通知 --> <bean id="authInterceptor" class="com.cathy.demo.spring.aop.AuthInterceptor" /> <!-- 定义通知 器 --> <bean id="authAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="pattern" value=".*" /> <property name="advice" ref="authInterceptor" /> </bean> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" p:usePrefix="true" p:advisorBeanNamePrefix="auth" /> <bean id="aopDemo" class="com.cathy.demo.spring.aop.AopDemo" /> </beans> <!-- 使用aop命名空间进行配置 --> <beans profile="three"> <bean id="authInterceptor" class="com.cathy.demo.spring.aop.BeforeInterceptor" /> <bean id="aopDemo" class="com.cathy.demo.spring.aop.AopDemo" /> <aop:config> <aop:aspect ref="authInterceptor"> <aop:before method="before" pointcut="execution(* *.*(..))" /> </aop:aspect> </aop:config> </beans> <!-- 自动扫描 @Aspectj --> <beans profile="four"> <aop:aspectj-autoproxy /> <context:annotation-config /> <context:component-scan base-package="com.cathy.demo.spring.*" /> </beans> </beans>
?
/** * * * @author zhangwei_david * @version $Id: SpringAopTest.java, v 0.1 2015年7月10日 上午10:51:16 zhangwei_david Exp $ */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath*:META-INF/spring/aop-beans.xml") @ActiveProfiles("four") public class SpringAopFourTest { @Autowired private Say aopDemo; @Test public void test() { aopDemo.say(); } }
?
原文:http://zhangwei-david.iteye.com/blog/2226203