学习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类里

学习Spring的第十五天_第1张图片

最后 , 配置文件不可少

用xml配置方式配置spring容器




    
    
    
    

    


    

 在测试类里测试即可

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

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

学习Spring的第十五天_第2张图片

你可能感兴趣的:(学习,spring,java,后端)