Spring家族-AOP使用方式

        Spring的AOP使用通常是通过注解方式使用,这里我想记录一下通过接口方式使用AOP功能,这样能够帮助我更加深入理解AOP原理。

一、ProxyFactory

        这种方式比较底层的,脱离Spring容器管理

public class MemberService {
    private String clusterName;

    public MemberService() {
    }

    public void testMember() {
        System.out.println("hello test");
    }

    @Override
    public String toString() {
        return "MemberService{" +
                "clusterName='" + clusterName + '\'' +
                '}';
    }
}
public class App {
    public static void main(String[] args) {
        MemberService memberService = new MemberService();
        memberService.setClusterName("hello member");

        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(memberService);
        factory.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object proceed = invocation.proceed();
                System.out.println("after...");
                return proceed;
            }
        });

        MemberService proxyMemberService = (MemberService)factory.getProxy();
        proxyMemberService.testMember();
    }
}

二、ProxyFactoryBean

MemberService类同上所示。注入ProxyFactoryBean对象即可。

@Configuration
public class AppConfig {
    @Bean
    public ProxyFactoryBean memberServiceProxy() {
        MemberService memberService = new MemberService();

        ProxyFactoryBean bean = new ProxyFactoryBean();
        bean.setTarget(memberService);
        bean.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object proceed = invocation.proceed();
                System.out.println("after...");
                return proceed;
            }
        });
        return bean;
    }

}
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example");
        MemberService memberServiceProxy = context.getBean("memberServiceProxy", MemberService.class);
        memberServiceProxy.testMember();
    }
}

三、BeanNameAutoProxyCreator

以上两种方式,都需要我们手动创建对象,并不能直接使用Spring容器内bean对象。下面这种方式是可以解决的,这里的MemberService需要用@Component进行注入

@Component
public class MemberService {
    private String clusterName;

    public MemberService() {
    }

    public void testMember() {
        System.out.println("hello test");
    }
    
    @Override
    public String toString() {
        return "MemberService{" +
                "clusterName='" + clusterName + '\'' +
                '}';
    }
}
@Configuration
public class AppConfig {

    @Bean
    public MethodInterceptor myInterceptor() {
        return new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object proceed = invocation.proceed();
                System.out.println("after...");
                return proceed;
            }
        };
    }
    @Bean
    public BeanNameAutoProxyCreator autoProxyCreator() {
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
        beanNameAutoProxyCreator.setBeanNames("member*");//代理以member开始所有bean对象
        beanNameAutoProxyCreator.setInterceptorNames("myInterceptor");//指定拦截器名字,即增强逻辑bean
        return beanNameAutoProxyCreator;
    }
}

四、DefaultPointcutAdvisor

这里是Advisor不是Advice,通过注入两个Bean对象,就可以增强任何类中带有test的方法,如下所示:

@Configuration
public class AppConfig {

    @Bean
    public DefaultPointcutAdvisor pointcutAdvisor() {
        NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
        pointcut.setMappedName("test*");
        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
        defaultPointcutAdvisor.setPointcut(pointcut);
        defaultPointcutAdvisor.setAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...");
                Object proceed = invocation.proceed();
                System.out.println("after...");
                return proceed;
            }
        });
        return defaultPointcutAdvisor;
    }


    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }
}

@Component
public class MemberService {
    private String clusterName;

    public MemberService() {
    }

    public void testMember() {
        System.out.println("hello test");
    }

    @Override
    public String toString() {
        return "MemberService{" +
                "clusterName='" + clusterName + '\'' +
                '}';
    }
}
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example");
        MemberService memberServiceProxy = context.getBean("memberService", MemberService.class);
        memberServiceProxy.testMember();
    }
}

 五、总结

        Spring提供的AOP方式有很多,这里罗列一些可能会用到的接口,其中第4个接口是最强大的,后面可以深入研究一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值