美文网首页
Spring AOP学习笔记

Spring AOP学习笔记

作者: 代码potty | 来源:发表于2018-07-30 18:33 被阅读0次

目前AOP的动态代理有两部分的实现
第一部分是SDK,使用动态代理可以为一个或多个接口在运行期动态生成实现对象,生成的对象中实现接口的方法时可以添加增强代码,从而实现AOP。缺点是只能针对接口进行代理,另外由于动态代理是通过反射实现的,有时可能要考虑反射调用的开销。
第二部分是CGLIB, 动态字节码生成技术是指在运行时动态生成指定类的一个子类对象,并覆盖其中特定方法,覆盖方法时可以添加增强代码,从而实现AOP。其常用工具是cglib。

以下是关于第一部分SDK使用的笔记
AOP中的切面封装了增强(Advice)和切点(Pointcut),下面先介绍增强

接口定义:

    public interface Greeting {
        public void shout(String name);
    }

接口的实现类定义:

    public class GreetingImpl implements Greeting {
        @Override
        public void shout(String name) {
            System.out.println("hello:"+name);
        }
    }

前置advice和后置advice

    public class GreetingBeforeAndAfter implement MethodBeforeAdvice,AfterReturnAdvice{
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println("before");
        }
    
        public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println("after");
        }
    }

测试类:

    @Test
    public void test(){
        ProxyFactory proxy = new ProxyFactory();
        proxy.setTarge(new GreetingImpl());
        proxy.addAdvice(new GreetingBeforeAndAfter());
    
        Greeting greet = (Greeting) proxy.getProxy();
        greeting.shout("小法");
    }

除了前置和后置的advice,还有个环绕增强类,需要实现接口org.aopalliance.intercept.MethodInterceptor。

    public class GreetingBeforeAndAfterAdvice implements MethodInterceptor {
    
        @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    
            before();
            Object result = methodInvocation.proceed();
            after();
            return result;
        }
    
        public void before(){
            System.out.println("before");
        }
    
        public void after(){
            System.out.println("after");
        }
    }

将测试类中proxy工厂的一些参数写到xml文件中

     <bean id="GreetingImpl" class="org.seckill.dao.aop.GreetingImpl" />
        <bean id="GreetingBeforeAndAfterAdvice" class="org.seckill.dao.aop.GreetingBeforeAndAfterAdvice"/>
        <bean id="GreetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="interfaces" value="org.seckill.dao.aop.Greeting" />
            <property name="target" ref="GreetingImpl" />
            <property name="interceptorNames" value="GreetingBeforeAndAfterAdvice" />
        </bean>

这样就可以直接在测试类可以通过获取applicationContext的对象调用getBean()方法来获取proxy工厂

以上的做法是对方法的增强,称为织入,对于类的增强称为引入增强
在不改上述例子的情况下,创建一个新的接口名为Love

    public interface Love {
        void display(String name);
    }

接着再创建一个advice(通知)继承一个引入(Introduction)的拦截器(Interceptor),并且实现这个接口。

    public class LoveAdvice extends DelegatingIntroductionInterceptor implements Love {
    
       /* @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            return super.invoke(methodInvocation);
        }*/
    
        @Override
        public void display(String name) {
            System.out.println(name);
        }
    }

然后修改xml文档,将代理服务器proxy注册到spring容器中

    <bean id="LoveAdvice" class="org.seckill.dao.aop.LoveAdvice" />
        <bean id="LoveProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="interfaces" value="org.seckill.dao.aop.Love" />
            <property name="target" ref="GreetingImpl" />
            <property name="interceptorNames" value="LoveAdvice" />
            <property name="proxyTargetClass" value="true" />
        </bean>

其中的属性proxyTargetClass默认是false,将它置为true,将使用CGLIB的动态代理,
最后写个测试类进行测试结果

    @Test
        public void testAOP(){
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-config.xml");
            GreetingImpl greeting = context.getBean("LoveProxy",GreetingImpl.class);
            greeting.shout("小法");
    
            Love love = (Love) greeting;
            love.display("asd");
        }

Love love = (Love) greeting是将目标类强制向上转型为Love接口,这就是引入增强(DelegatingIntroductionInterceptor)的特性。

参考链接地址:https://www.cnblogs.com/zhaozihan/p/5953063.html

相关文章

网友评论

      本文标题:Spring AOP学习笔记

      本文链接:https://www.haomeiwen.com/subject/gipfvftx.html