• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Spring AOP之传统AOP的动态代理

编程语言 Geekerstar 1年前 (2018-05-29) 801次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

自动代理的方式的介绍

自动创建代理

前面的开发案例中,每个代理都是同ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBena开发的维护量是巨大的,也是非常麻烦的。

解决方案:自动创建代理

– BeanNameAutoProxyCreator 根据Bean名称创建代理

– DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理

– AnnotationAwareAspectJAutoProxyCreator 基于Bean中的AspectJ注解进行自动代理

基于Bean名称的自动代理

对所有以DAO结尾的Bean所有方法使用代理

代码演示

新建一个demo5,从demo3和demo4中将下面这几个类拿过来

新建一个配置文件applicationContext3.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置目标类-->
    <bean id="studentDao" class="com.jikewenku.aop.demo5.StudentDaoImpl"/>
    <bean id="customerDao" class="com.jikewenku.aop.demo5.CustomerDao"/>

    <!-- 配置增强-->
    <bean id="myBeforeAdvice" class="com.jikewenku.aop.demo5.MyBeforeAdvice"/>
    <bean id="myAroundAdvice" class="com.jikewenku.aop.demo5.MyAroundAdvice"/>

    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames" value="*Dao"/>
        <property name="interceptorNames" value="myBeforeAdvice"/>
    </bean>
</beans>

准备工作完成了,接下来我们进行测试,创建一个SpringDemo5

package com.jikewenku.aop.demo5;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.<a href="https://www.jikewenku.com/tag/spring" title="查看更多关于Spring的文章" target="_blank">Spring</a>JUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(<a href="https://www.jikewenku.com/tag/spring" title="查看更多关于Spring的文章" target="_blank">Spring</a>JUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class <a href="https://www.jikewenku.com/tag/spring" title="查看更多关于Spring的文章" target="_blank">Spring</a>Demo5 {
    @Resource(name="studentDao")
    private StudentDao studentDao;
    @Resource(name="customerDao")
    private CustomerDao customerDao;

    @Test
    public void demo1(){
        studentDao.find();
        studentDao.save();
        studentDao.update();
        studentDao.delete();

        customerDao.find();
        customerDao.save();
        customerDao.update();
        customerDao.delete();

    }
}

接下来运行一下它,看具体实现的结果是什么

如图,可以看到我们所有类的所有方法都使用了前置增强,也就是说根据目标类的名称然后自动来产生代理,这就是基于Bean名称的自动代理,这种方式比前面的方式更灵活一点,但是还有一点问题就是,如果我想增强这个类里面的save方法,那么应该怎么做呢?这种方式又不太合适了,下面我们再介绍一种比较合适的方式。

基于切面信息的自动代理

DefaultAdvisorAutoProxyCreator举例

如果我们想对某些类里面的某些方法进行代理,我们就可以使用下面这种方式。

配置环绕代理案例

代码演示

新建demo6,将demo5里的文件复制过来,新建一个配置文件applicationContext4.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置目标类-->
    <bean id="studentDao" class="com.jikewenku.aop.demo6.StudentDaoImpl"/>
    <bean id="customerDao" class="com.jikewenku.aop.demo6.CustomerDao"/>

    <!-- 配置增强-->
    <bean id="myBeforeAdvice" class="com.jikewenku.aop.demo6.MyBeforeAdvice"/>
    <bean id="myAroundAdvice" class="com.jikewenku.aop.demo6.MyAroundAdvice"/>

    <!--配置切面-->
    <bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="pattern" value="com\.imooc\.aop\.demo6\.CustomerDao\.save"/>
        <property name="advice" ref="myAroundAdvice"/>
    </bean>

    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
</beans>

新建一个测试类SpringDemo6

package com.jikewenku.aop.demo6;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.<a href="https://www.jikewenku.com/tag/spring" title="查看更多关于Spring的文章" target="_blank">Spring</a>JUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext4.xml")
public class SpringDemo6 {
    @Resource(name="studentDao")
    private StudentDao studentDao;
    @Resource(name="customerDao")
    private CustomerDao customerDao;

    @Test
    public void demo1(){
        studentDao.find();
        studentDao.save();
        studentDao.update();
        studentDao.delete();

        customerDao.find();
        customerDao.save();
        customerDao.update();
        customerDao.delete();

    }
}

运行程序,观察结果。

可以看到只有客户进行了环绕增强。


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Spring AOP之传统AOP的动态代理
喜欢 (0)
[247507792@qq.com]
分享 (0)
Geekerstar
关于作者:
本站技术支持

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00