SpringAOP拦截-三种⽅式实现⾃动代理详解
这⾥的⾃动代理,我讲的是⾃动代理bean对象,其实就是在xml中让我们不⽤配置代理⼯⼚,也就是不⽤配置class为org.springframework.aop.framework.ProxyFactoryBean的bean。
总结了⼀下⾃⼰⽬前所学的知识。
发现有三种⽅式实现⾃动代理
⽤Spring⼀个⾃动代理类DefaultAdvisorAutoProxyCreator:
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" data-filtered="filtered"></bean>
例如:
原来不⽤⾃动代理的配置⽂件如下:
<!--?xml version="1.0" encoding="UTF-8"?-->
<beans xmlns="/schema/beans" xmlns:context="www.springfram
/schema/tx /schema/tx/spring-tx-4.3.xsd">
<!-- 代理前原对象 -->
<bean class="lImpl.Person" id="person"></bean>
<!-- 切⾯ = 切点+通知 -->
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor">
<!-- 切点 -->
<property name="patterns">
<list>
<value>.*run.*</value>
</list>
</property>
<!-- 通知-由我们写,实际代理动作 -->
<property name="advice">
<bean class="lImpl.AroundAdvice" id="advice"></bean>
</property>
</bean>
<!-- 代理⼯⼚ -->
<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="personProxied">
<!-- 放⼊原型对象 -->
<property name="target" ref="person"></property>
<!-- 放⼊切⾯ -->
<property name="interceptorNames">
<list>
<value>advisor</value>
</list>
</property>
</bean>
</beans>
现在改⽤⾃动代理,如下配置:
<beans ...="">
<!-- 代理前原对象 -->
<bean class="lImpl.Person" id="person"></bean>
<!-- 切⾯ = 切点+通知 -->
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor">
<!-- 切点 -->
<property name="patterns">
<list>
<value>.*run.*</value>
</list>
</property>
<!-- 通知-由我们写,实际代理动作 -->
<property name="advice">
<bean class="lImpl.AroundAdvice" id="advice"></bean>
</property>
</bean>
<!-- ⾃动代理 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
</beans>
测试⽅法
@Test//⾃动代理
public void demo4(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/l");
//我们直接在这⾥获取Person对象就可以了,因为在最开始xml⽂件newPerson对象后,Spring就已经帮我们代理了!
Person p =Bean(Person.class);
p.run();
p.say();
}
相对于前⾯,也就是把代理⼯⼚部分换成⾃动代理了。
演⽰结果:
⾃⼰写⼀个⾃动代理底层实现:
我们也可以写⼀个类,来实现DefaultAdvisorAutoProxyCreator⾃动代理的功能!
⾸先,我们需要实现⼀个接⼝,也就是BeanPostProcessor接⼝。
BeanPostProcessor接⼝作⽤是:如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加⼀些⾃⼰的逻辑处理,我们就可以定义⼀个或者多个BeanPostProcessor接⼝的实现,然
后注册到容器中。
⽽我们想要在原型对象bean被创建之后就代理了,就必须在原来的容器中拿到原来的原型对象,需要拿到原来spring容器中的切⾯对象,这个时候,我们就需要原来的容器,这个时候就需要另⼀个接
⼝,也就是ApplicationContextAware接⼝!
通过这2个接⼝,我们就可以实现⾃动代理了。
package lImpl;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.fig.BeanPostProcessor;
import t.ApplicationContext;
import t.ApplicationContextAware;
public class MyAutoProxy implements BeanPostProcessor,ApplicationContextAware{
private ApplicationContext applicationContext=null;
//bean创建之前调⽤
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;//在这⾥,我们直接放⾏
}
//bean创建之后调⽤
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
ProxyFactoryBean factory = new ProxyFactoryBean();
//把原型对象放⼊代理⼯⼚
factory.setTarget(bean);
//在这⾥
Advisor adv = Bean(Advisor.class);
factory.addAdvisor(adv);
//返回被代理后的对象
Object();
}
//拿到原来的spring中的容器
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext=applicationContext;
}
}
&>
<!-- 代理前原对象 -->
<bean class="lImpl.Person" id="person"></bean>
<!-- 切⾯ = 切点+通知 -->
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor">
<!-- 切点 -->
<property name="patterns">
<list>
<value>.*run.*</value>
</list>
</property>
<!-- 通知-由我们写,实际代理动作 -->
<property name="advice">
<bean class="lImpl.AroundAdvice" id="advice"></bean>
</property>
</bean>
<!-- ⾃⼰写的⾃动代理 -->
<bean class="lImpl.MyAutoProxy"></bean>
</>
测试⽅法:
@Test//⾃⼰实现的⾃动代理
public void demo5(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/l");
Person p =Bean(Person.class);
p.run();
p.say();
}
测试结果就不上图了,和前⾯是⼀样的。
实例化bean的三种方式其实很多时候,我们如果⾃⼰去练⼀下底层,对上层的框架更好理解。
还有⼀种⽅法。
使⽤aop标签配⾃动代理
需要在beans加⼀个命名空间
还需要配xsi:schemaLocation,为aop加⼀个⽹络地址。
我们需要⼀个aspectjweaver-jar包:
xml配置⽂件:
<!--?xml version="1.0" encoding="UTF-8"?-->
<beans xmlns="/schema/beans" xmlns:aop="/schema/aop" xmlns:context="/schema/context" xmlns:tx="/schema/tx" xmlns:xsi= /schema/context /schema/context/spring-context-4.3.xsd
/schema/tx /schema/tx/spring-tx-4.3.xsd
/schema/aop /schema/aop/spring-aop-4.3.xsd ">
<!-- 利⽤sop标签实现⾃动代理 -->
</aop:aspectj-autoproxy>
<!-- 代理前原对象 -->
<bean class="lImpl.Person" id="person"></bean>
<!-- 切⾯ = 切点+通知 -->
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="advisor">
<!-- 切点 -->
<property name="patterns">
<list>
<value>.*run.*</value>
</list>
</property>
<!-- 通知-由我们写,实际代理动作 -->
<property name="advice">
<bean class="lImpl.AroundAdvice" id="advice"></bean>
</property>
</bean>
</beans>
测试⽅法:
@Test//⾃动代理
public void demo6(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/l");
Person p =Bean(Person.class);
p.run();
p.say();
}
测试结果:
个⼈觉得能学会使⽤⼀种就OK了,不⽤全部记下来,为了学习,都了解⼀下就好,别⼈写出来,能看懂就好。
哈哈,其实底层学好了,⾃⼰写的时候,就算不会⽤Spring的⾃动代理,⾃⼰写出来底层也是蛮好的嘛
总结
以上本⽂关于Spring AOP拦截-三种⽅式实现⾃动代理详解的全部内容,希望对⼤家有所帮助。感兴趣的朋友可以继续参阅本站:、、等,有什么问题可以随时留⾔,⼩编会及时回复⼤家的。感谢朋友们对本站的⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论