浅谈spring——自动创建代理(八)
2013-04-29 10:52
381 查看
浅谈spring——切面(七)这一节提到通常要借助ProxyFactoryBean创建织入切面的代理子类,虽然对目标类进行了增强,但是增加了很多额外的配置。
spring提供自动代理机制,可以帮我们从烦琐的工作中解救出来。其实现机制借助于BeanPostProcessor的自动代理创建器的实现类。
自动代理创建器的继承关系:
代理器有三类:
1. 基于Bean的名字的自动代理创建器,例如BeanNameAutoProxyCreator.java
2. 基于Advisor(切面)匹配机制的自动代理创建器。对spring容器中的所有的Advisor扫描,并将其应用到匹配的Bean中。例如DefaultAdvisorAutoProxyCreator.java
3. 基于Bean中的AspjectJ注解标签的自动代理创建器,例如AnnotationAwareAspectJAutoProxyCreator.java
所有的自动代理创建器,都是实现了BeanPostProcessor。spring容器在实例化Bean时,BeanPostProcessor会对其加工,对满足匹配规则的Bean自动创建代理对象。
BeanNameAutoProxyCreator代码示例:
xml配置文件
beanNames可以使用 * 作通配符,也可以使用具体的bean名字,如
p:interceptorNames指定一个或多个增强Bean的名称,可以是增强bean,也可以是切面bean
p:optimize 强制使用CGLib动态代理
DefaultAdvisorAutoProxyCreator能够扫描容器中的Advisor,并将Advisor自动织入到匹配的目标Bean中,即为匹配的目标Bean自动创建代理
代码实例:
xml配置文件:
测试类:
结果:
-----------begin---------------
GreetingBeforeAdvice is successfully called! tome.sample.Advisor.Waiter.greetTo
How are you!Tom1!
-----------end---------------
waiter greet to Tom1!
waiter serving Tom2!
seller greet to Tom3!
总结:
1. Spring采用JDK动态代理和CGLib动态代理在运行期织入增强,所以不需要要装备特殊的编译器或类装载器就可以使用AOP的功能。JDK动态代理面向的是接口层面,有很大的局限性;而CGLib不会对目标类做任何限制。JDK动态代理在创建对象时性能较好,但运行时性能较差,CGLib正好相反,所以如果创建的是singleton对象,我们比较青睐使用CGLib的动态代理
2. Spring有方法层面上有4类增强:前置增强、后置增强、环绕增强、抛出异常时的增强。引介增强是类级别的,它为目标类织入新的接口实现。
增强是一种简单的切面,作用于所有方法。
3. 切点是通过目标类名和方法名来定位一个连接点
4. 切面是切点和增强的联合体,通过ProxyFactoryBean将切面织入到不同的目标类中。当然如果要创建的代理子类太多,可以借助自动代理创建器,将容器中的Advisor自动织入到目标Bean中
spring提供自动代理机制,可以帮我们从烦琐的工作中解救出来。其实现机制借助于BeanPostProcessor的自动代理创建器的实现类。
自动代理创建器的继承关系:
代理器有三类:
1. 基于Bean的名字的自动代理创建器,例如BeanNameAutoProxyCreator.java
2. 基于Advisor(切面)匹配机制的自动代理创建器。对spring容器中的所有的Advisor扫描,并将其应用到匹配的Bean中。例如DefaultAdvisorAutoProxyCreator.java
3. 基于Bean中的AspjectJ注解标签的自动代理创建器,例如AnnotationAwareAspectJAutoProxyCreator.java
所有的自动代理创建器,都是实现了BeanPostProcessor。spring容器在实例化Bean时,BeanPostProcessor会对其加工,对满足匹配规则的Bean自动创建代理对象。
BeanNameAutoProxyCreator代码示例:
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:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <!-- 普通方法名匹配切面 --> <bean id="waiter" class="tome.sample.Advisor.Waiter" /> <bean id="seller" class="tome.sample.Advisor.Seller" /> <bean id="greetingAdvice" class="tome.sample.Advisor.GreetingBeforeAdvice" /> <!-- 通过Bean名称自动创建代理 --> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" p:interceptorNames="greetingAdvice" p:optimize="true"> <property name="beanNames" value="*er" /> </bean> </beans>注意:
beanNames可以使用 * 作通配符,也可以使用具体的bean名字,如
<property name="beanNames" value="waiter,seller" />
p:interceptorNames指定一个或多个增强Bean的名称,可以是增强bean,也可以是切面bean
p:optimize 强制使用CGLib动态代理
DefaultAdvisorAutoProxyCreator能够扫描容器中的Advisor,并将Advisor自动织入到匹配的目标Bean中,即为匹配的目标Bean自动创建代理
代码实例:
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:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <!-- 普通方法名匹配切面 --> <bean id="waiter" class="tome.sample.Advisor.Waiter" /> <bean id="seller" class="tome.sample.Advisor.Seller" /> <bean id="greetingAdvice" class="tome.sample.Advisor.GreetingBeforeAdvice" /> <bean id="greetingAdvisor" class="tome.sample.Advisor.GreetingAdvisor"> <property name="advice" ref="greetingAdvice" /> </bean> <!--通过Advisor自动创建代理--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" /> </beans> </beans>
测试类:
public static void main(String[] args) { String configPath = "tomge/sample/Advisor/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter waiter = (Waiter) ctx.getBean("waiter"); Seller seller = (Seller) ctx.getBean("seller"); waiter.greetTo("Tom1"); waiter.serveTo("Tom2"); seller.greetTo("Tom3"); }
结果:
-----------begin---------------
GreetingBeforeAdvice is successfully called! tome.sample.Advisor.Waiter.greetTo
How are you!Tom1!
-----------end---------------
waiter greet to Tom1!
waiter serving Tom2!
seller greet to Tom3!
总结:
1. Spring采用JDK动态代理和CGLib动态代理在运行期织入增强,所以不需要要装备特殊的编译器或类装载器就可以使用AOP的功能。JDK动态代理面向的是接口层面,有很大的局限性;而CGLib不会对目标类做任何限制。JDK动态代理在创建对象时性能较好,但运行时性能较差,CGLib正好相反,所以如果创建的是singleton对象,我们比较青睐使用CGLib的动态代理
2. Spring有方法层面上有4类增强:前置增强、后置增强、环绕增强、抛出异常时的增强。引介增强是类级别的,它为目标类织入新的接口实现。
增强是一种简单的切面,作用于所有方法。
3. 切点是通过目标类名和方法名来定位一个连接点
4. 切面是切点和增强的联合体,通过ProxyFactoryBean将切面织入到不同的目标类中。当然如果要创建的代理子类太多,可以借助自动代理创建器,将容器中的Advisor自动织入到目标Bean中
相关文章推荐
- 代理匹配浅谈spring——自动创建代理(八)
- spring用BeanNameAutoProxyCreator自动创建事务代理
- Spring-AOP 自动创建代理之BeanNameAutoProxyCreator
- Spring事务--非注解--自动代理创建器[spring2.0]
- Spring-AOP 自动创建代理之DefaultAdvisorAutoProxyCreator
- spring(一) spring用BeanNameAutoProxyCreator自动创建事务代理
- spring用BeanNameAutoProxyCreator自动创建事务代理
- 详解在Spring中如何自动创建代理
- JavaWeb学习笔记-spring-15-AOP-自动创建代理
- spring用BeanNameAutoProxyCreator自动创建事务代理
- 【Spring AOP】自动创建代理
- spring用BeanNameAutoProxyCreator自动创建事务代理
- Spring-AOP 自动创建代理之AnnotationAwareAspectJAutoProxyCreator
- Spring中创建切面 --- 自动代理
- Spring自动创建异常抛出增强代理
- Spring AOP 自动创建代理
- Spring-AOP 自动创建代理
- Spring 自动代理创建器详细介绍及简单实例
- Spring AOP 自动创建代理
- Spring之自动创建代理