Spring AOP 方式三 BeanNameAutoProxyCreator
例子
IHello 接口类
package com.benx.mvc; public interface IHello { public void say(); }
IHello接口实现类
package com.benx.mvc; public class HelloImpl implements IHello { public void say() { System.out.println("Hello World"); } }
拦截器
package com.benx.mvc; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HelloInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation methodinvocation) throws Throwable { System.out.println("start"); Object ob = methodinvocation.proceed(); System.out.println("end"); return ob; } }
spring.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" 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/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:component-scan base-package="com.benx.mvc" /> <bean id="hello1" class="com.benx.mvc.HelloImpl" /> <bean id="hello2" class="com.benx.mvc.HelloImpl" /> <bean id="helloInterceptor" class="com.benx.mvc.HelloInterceptor" /> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames" value="hel*" /> <property name="interceptorNames"> <list> <value>helloInterceptor</value> </list> </property> </bean> </beans>
测试类
package com.benx.mvc; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanNameAutoProxyCreatorTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); IHello hello1 = (IHello) context.getBean("hello1"); hello1.say(); IHello hello2 = (IHello) context.getBean("hello1"); hello2.say(); } }
结果:
start
Hello World
end
start
Hello World
end
实现原理:
1、BeanNameAutoProxyCreator父类AbstractAutoProxyCreator 继承接口InstantiationAwareBeanPostProcessor,其方法postProcessBeforeInstantiation 在 Bean实例创建之前使用。
2、Spring在初始化Bean时,优先调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation,如果该方法不为NULL,那么直接返回该对象。BeanNameAutoProxyCreator就是使用该方式,返回代理对象。
3、创建代理对象,实际也是使用ProxyFactory来返回代理。