学习Spring的第十五天

spring aop动态代理开发

一、什么是动态代理

动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作。

     代理类在程序运行期间,创建的代理对象称之为动态代理对象。这种情况下,创建的代理对象,并不是事先在Java代码中定义好的。而是在运行期间,根据我们在动态代理对象中的“指示”,动态生成的。也就是说,你想获取哪个对象的代理,动态代理就会为你动态的生成这个对象的代理对象。动态代理可以对被代理对象的方法进行功能增强。有了动态代理的技术,那么就可以在不修改方法源码的情况下,增强被代理对象的方法的功能,在方法执行前后做任何你想做的事情。

Spring Aop 面向切面编程

面向切面编程采用动态代理的方式进行对相关方法增强

以下采用JDK官方提供的Proxy类创建代理对象

代码如下

public class MockAopBeanPostProcessor implements BeanPostProcessor , ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //目的:对UserServiceImpl中的show1和show2方法进行增强,增强方法存在与MyAdvice中
        //问题1:筛选service.impl包下的所有的类的所有方法都可以进行增强,解决方案if-else
        //问题2:MyAdvice怎么获取到?解决方案:从Spring容器中获得MyAdvice
        if(bean.getClass().getPackage().getName().equals("com.itheima.service.impl")){
            //生成当前Bean的Proxy对象
            Object beanProxy = Proxy.newProxyInstance(
                    bean.getClass().getClassLoader(),
                    bean.getClass().getInterfaces(),
                    (Object proxy, Method method, Object[] args) -> {
                        MyAdvice myAdvice = applicationContext.getBean(MyAdvice.class);
                        //执行增强对象的before方法
                        myAdvice.beforeAdvice();
                        //执行目标对象的目标方法
                        Object result = method.invoke(bean, args);
                        //执行增强对象的after方法
                        myAdvice.afterAdvice();
                        return result;
                    }
            );

            return beanProxy;
        }

        return  bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

其实我们对UserService进行了增强

UserServiceImpl继承了UserService接口 , 

增强对象的增强方法我们设置在MyAdvice类里

最后 , 配置文件不可少

用xml配置方式配置spring容器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       ">

    <!--配置目标类-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
    <!--配置的通知类-->
    <bean id="myAdvice" class="com.itheima.advice.MyAdvice"></bean>

    <bean class="com.itheima.processor.MockAopBeanPostProcessor"></bean>


    </beans>

 在测试类里测试即可

 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService bean = app.getBean(UserService.class);
        bean.show1();

方法show1()得到了增强 (其实UserServiceImpl里的每一个方法都得到了增强, 在此演示show1())

相关推荐

  1. 学习Spring

    2024-02-08 03:26:01       36 阅读
  2. 开始学习

    2024-02-08 03:26:01       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-08 03:26:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-08 03:26:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-08 03:26:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-08 03:26:01       20 阅读

热门阅读

  1. 谈谈mybatis的理解(三)

    2024-02-08 03:26:01       33 阅读
  2. vim最简单命令学习

    2024-02-08 03:26:01       41 阅读
  3. 开源软件的未来发展趋势

    2024-02-08 03:26:01       31 阅读
  4. 自定义 Linux 快捷命令

    2024-02-08 03:26:01       25 阅读
  5. 在容器外通过tcpdump对容器内的网络抓包方法

    2024-02-08 03:26:01       31 阅读
  6. go 切面 AOP 实现

    2024-02-08 03:26:01       28 阅读
  7. 让macOS外接键盘Home/End键可用

    2024-02-08 03:26:01       33 阅读
  8. vue 用的watch 的说明及例子

    2024-02-08 03:26:01       29 阅读
  9. 一次ceph节点时钟同步异常排查总结

    2024-02-08 03:26:01       28 阅读
  10. 瑞芯微推理RKNN使用

    2024-02-08 03:26:01       36 阅读