文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring AOP中如何实现自动代理

2023-05-30 22:39

关注

小编给大家分享一下Spring AOP中如何实现自动代理,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

这里的自动代理,我讲的是自动代理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="https://www.springframework.org/schema/beans" xmlns:context="https://www.springframework.org/schema/context" xmlns:tx="https://www.springframework.org/schema/tx" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-4.3.xsd        https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-4.3.xsd        https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.3.xsd">  <!-- 代理前原对象 -->  <bean class="cn.hncu.xmlImpl.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="cn.hncu.xmlImpl.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="cn.hncu.xmlImpl.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="cn.hncu.xmlImpl.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/xmlImpl/4.xml");    //我们直接在这里获取Person对象就可以了,因为在最开始xml文件newPerson对象后,Spring就已经帮我们代理了!    Person p =ctx.getBean(Person.class);    p.run();    p.say();  }

相对于前面,也就是把代理工厂部分换成自动代理了。

演示结果:

Spring AOP中如何实现自动代理

自己写一个自动代理底层实现:

我们也可以写一个类,来实现DefaultAdvisorAutoProxyCreator自动代理的功能!

首先,我们需要实现一个接口,也就是BeanPostProcessor接口。

BeanPostProcessor接口作用是:如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProcessor接口的实现,然后注册到容器中。

而我们想要在原型对象bean被创建之后就代理了,就必须在原来的容器中拿到原来的原型对象,需要拿到原来spring容器中的切面对象,这个时候,我们就需要原来的容器,这个时候就需要另一个接口,也就是ApplicationContextAware接口!

通过这2个接口,我们就可以实现自动代理了。

package cn.hncu.xmlImpl;import org.springframework.aop.Advisor;import org.springframework.aop.framework.ProxyFactoryBean;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.context.ApplicationContext;import org.springframework.context.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 = applicationContext.getBean(Advisor.class);    factory.addAdvisor(adv);    //返回被代理后的对象    return factory.getObject();  }  //拿到原来的spring中的容器  @Override  public void setApplicationContext(ApplicationContext applicationContext)      throws BeansException {    this.applicationContext=applicationContext;  }}

xml

<beans...><!-- 代理前原对象 -->  <bean class="cn.hncu.xmlImpl.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="cn.hncu.xmlImpl.AroundAdvice" id="advice"></bean>    </property>  </bean>    <!-- 自己写的自动代理 -->  <bean class="cn.hncu.xmlImpl.MyAutoProxy"></bean></beans...>

测试方法:

@Test//自己实现的自动代理  public void demo5(){    ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/xmlImpl/5.xml");    Person p =ctx.getBean(Person.class);    p.run();    p.say();  }

测试结果就不上图了,和前面是一样的。

其实很多时候,我们如果自己去练一下底层,对上层的框架更好理解。

还有一种方法。

使用aop标签配自动代理

需要在beans加一个命名空间

xmlns:aop=https://www.springframework.org/schema/aop

还需要配xsi:schemaLocation,为aop加一个网络地址。

https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.3.xsd

我们需要一个aspectjweaver-jar包:

xml配置文件:

<!--?xml version="1.0" encoding="UTF-8"?--><beans xmlns="https://www.springframework.org/schema/beans" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:context="https://www.springframework.org/schema/context" xmlns:tx="https://www.springframework.org/schema/tx" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-4.3.xsd        https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-4.3.xsd        https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.3.xsd        https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.3.xsd ">  <!-- 利用sop标签实现自动代理 -->  </aop:aspectj-autoproxy>   <!-- 代理前原对象 -->  <bean class="cn.hncu.xmlImpl.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="cn.hncu.xmlImpl.AroundAdvice" id="advice"></bean>    </property>  </bean> </beans>

测试方法:

@Test//自动代理  public void demo6(){    ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/xmlImpl/6.xml");    Person p =ctx.getBean(Person.class);    p.run();    p.say();  }

测试结果:

Spring AOP中如何实现自动代理

以上是“Spring AOP中如何实现自动代理”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯