Spring入门(AOP API,ProxyFactoryBean其三)
来源:互联网 发布:禁止外资参与网络出版 编辑:程序博客网 时间:2024/05/24 05:50
Proxying classes
前面的ppt图片例子中如果没有Person接口,或者代码例子中没有BizLogic接口,这种情况下Spring会使用CGLIB代理,而不是JDK动态代理
如果想,可以强制在任何情况下使用CGLIB,即使有接口
CGLIB代理的工作原理是在运行时生成目标类的子类,Spring配置这个生成的子类委托方法调用到原来的目标
子类是用来实现Decorator模式,织入通知
CGLIB的代理对用户是透明的。需要注意:
-final方法不能被通知,因为它们不能被覆盖
-不用把CGLIB添加到classpath中,在Spring3.2中,CGLIB被重新包装并包含在Spring核心的JAR(即基于CGLIB的AOP就像JDK动态代理一样“开箱即用”)
使用global advisors
用*做通配符,匹配所有拦截器加入通知链
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"/> <property name="interceptorNames"> <list> <value>global*</value> </list> </property></bean><bean id="global_debug" class="org.springframework.aop.interceptor.DebugInterceptor"/><bean id="global_performance" class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor"/>
在我们自己的例子中
<bean id="bizLogicImpl" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.imooc.aop.api.BizLogic</value> </property> <property name="target"> <bean class="com.imooc.aop.api.BizLogicImpl"></bean> <ref bean="bizLogicImplTarget"/> </property> <property name="interceptorNames"> <list> <value>moocBeforeAdvice</value> <value>moocAfterReturningAdvice</value> <value>moocMethodInterceptor</value> <value>moocThrowsAdvice</value> </list> </property> </bean>
可以把list标签中的内容改为<value>mooc*</value>
执行后发现只执行了moocMethodInterceptor方法,因为只有*匹配匹配所有拦截器,那么拦截器是什么,是interceptor,只有MoocMethodInterceptor实现了MethodInterceptor,其他的几个advice还是要像之前一样逐个配置进去。
简化的proxy定义
在spring中支持使用父子bean定义,以及内部bean定义。可能会带来更清洁和更简洁的代理定义(抽象属性标记父bean定义为抽象的,这样它不能被实例化,可以理解和abstract class是一样的)
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transacionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
接下来看如何来简化
<bean id="myService" parent="txProxyTemplate"> <property name="target"> <bean class="org.springframework.samples.MyServiceImpl> </bean> </property></bean>
parent是txProxyTemplate,也就是上边定义的bean的id。使用属性target,指向MyServiceImpl实现类。注意这个target,是parent里面的属性,在继承的时候可以为parent进行赋值。
再看下边这个例子:
<bean id="mySpecialService" parent="txProxyTemplate"> <property name="target"> <bean class="org.springframework.samples.MySpecialServiceImpl> </bean> </property> <property name="transactionAttributes"> <props> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="store*">PROPAGATION_REQUIRED</prop> </props> </property></bean>
parent和上边一样,target属性指向MySpecialServiceImpl这个实现类,同时,可以覆盖掉parent里边的transactionAttributes属性。
看一下我们自己之前的代码要如何实现
<bean id="moocBeforeAdvice" class="com.imooc.aop.api.MoocBeforeAdvice"></bean> <bean id="moocAfterReturningAdvice" class="com.imooc.aop.api.MoocAfterReturningAdvice"></bean> <bean id="moocMethodInterceptor" class="com.imooc.aop.api.MoocMethodInterceptor"></bean> <bean id="moocThrowsAdvice" class="com.imooc.aop.api.MoocThrowsAdvice"></bean> <bean id="baseProxyBean" class="org.springframework.aop.framework.ProxyFactoryBean" lazy-init="true" abstract="true"></bean> <bean id="bizLogicImpl" parent="baseProxyBean"> <property name="target"> <bean class="com.imooc.aop.api.BizLogicImpl"></bean> </property> <property name="proxyInterfaces"> <value>com.imooc.aop.api.BizLogic</value> </property> <property name="interceptorNames"> <list> <value>moocBeforeAdvice</value> <value>moocAfterReturningAdvice</value> <value>moocMethodInterceptor</value> <value>moocThrowsAdvice</value> </list> </property> </bean>
定义baseProxyFactory,指向ProxyFactoryBean。然后是定义自己的beanbizLogicImpl,parent是baseProxyFactory,同时在当前的bean里边设置target。然后是proxyInterfaces和interceptorNames,唯一有区别的就是指定了parent,通过parent来指向ProxyFactoryBean。
运行单元测试的结果没有变化
使用ProxyFactory
使用Spring AOP而不必依赖于Spring IOC(这是一种好处),使用方式:
ProxyFactory factory=new ProxyFactory(myBusinessInterfaceImpl);factory.addAdvice(myMethodInterceptor);factory.addAdvisor(myAdvisor);MyBusinessInterface tb=(MyBusinessInterface)factory.getProxy();
声明并创建ProxyFactory的对象,并把某一个对象赋值给它,然后addAdvice和addAdvisor,最后通过getProxy得到它所代理的那个对象。
大多数情况下最佳实践是用IOC容器创建AOP代理
虽然可以硬编码方式实现,但是Spring推荐使用配置或注解方式实现
使用“auto-proxy”
Spring也允许使用“自动代理”的bean定义,它可以自动代理选定的bean,这是建立在Spring的“bean post processor”功能基础上的(在加载bean的时候就可以修改)
主要通过BeanNameAutoProxyCreator来实现
<bean class="org.springframework.aop.framework.BeanNameAutoProxyCreator"> <property name="beanNames" value="jdk*,onlyJdk"/> <property name="interceptorNames"> <list> <value>myInterceptor</value> </list> </property></bean>
它会代理所有以jdk开始的这种bean,也包括onlyJdk,否则就会像刚才一样,每一个bean挨个指定parent或者最原始的方式,所以好处就是可以简化配置和开发。
使用DefaultAdvisorAutoProxyCreator,当前IOC容器中自动应用,不用显示声明引用advisor的bean定义。
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/><bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"> <property name="transactionInterceptor" ref="transactionInterceptor"/></bean><bean id="customAdvisor" class="com.mycompany.Myadvisor"/><bean id="businessObject1" class="com.mycompany.BusinessObject1"></bean><bean id="businessObject2" class="com.mycompany.BusinessObject2"></bean>
如果在当前的IOC容器声明了第一行,也就是DefaultAdvisorAutoProxyCreator这样的bea,那么它会在当前的IOC容器中自动应用,来达到创建代理的效果,使用它的时候不用显示引用advisor的bean定义
- Spring入门(AOP API,ProxyFactoryBean其三)
- Spring入门(AOP API、ProxyFactoryBean其一)
- Spring入门(AOP API、ProxyFactoryBean其二)
- Spring入门(Schema-based AOP其三)
- Spring AOP小测试(ProxyFactoryBean)
- Spring AOP-编程的方式创建代理类(ProxyFactoryBean)
- 浅析Spring AOP源码(十四) 分析ProxyFactoryBean
- Spring Aop(十三)——ProxyFactoryBean创建代理对象
- Spring AOP实现机制(二)--ProxyFactoryBean---将Spring AOP和Spring IoC容器相结合
- Spring入门(Schema-based AOP其四)
- Spring AOP之基于ProxyFactoryBean的代理
- Spring -- org.springframework.aop.framework.ProxyFactoryBean
- Spring AOP之ProxyFactoryBean与BeanNameAutoProxyCreator
- Spring学习笔记 —— AOP(面向切面编程) 之使用ProxyFactoryBean实现AOP
- Spring入门介绍-AOP(三)
- spring aop入门(序列三)
- 做一个合格的程序猿之浅析Spring AOP源码(十四) 分析ProxyFactoryBean
- 用ProxyFactoryBean创建AOP代理(转)
- JVM内存区域划分
- Amazon Dynamo架构分析(一)
- 年底阅读计划
- 列表生成器笔记(Python)
- shiro 返回 json
- Spring入门(AOP API,ProxyFactoryBean其三)
- Hexo+Next主题 文章添加阅读次数,访问量等
- 从奈奎斯特定理到香农定理
- (88)单例模式的应用
- Colored Sticks --欧拉回路,并查集,字典树,
- mybatis和spring的优缺点:
- javaWeb-web项目中加载资源文件路径的两种方式
- 日常笔记-内部类
- JavaScript中的正则表达式