• 暂时停更一段时间!
  • 近期网站将陆续进行前端页面改造!
  • 招募网站编辑,联系站长!

Spring AOP之传统AOP的动态代理

文章目录[隐藏]

自动代理的方式的介绍

自动创建代理

前面的开发案例中,每个代理都是同 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)

邀请您免费 注册账号 登录 即可参与讨论!