spring-编程AOP使用

tech2023-07-19  94

文章目录

前言配置切面ProxyFactoryProxyFactoryBean配置通知配置类定义目标类上下文类 参考

前言

编程AOP ,编程AOP ,为啥要了解编程AOP呢,因为实际上 我们用的AOP 操作都是基于编程来做的,只是 spring帮你做了一些操作,所以了解编程AOP 实际上对源码的理解还是有一定的作用的,也就明白了源码中 一些 为什么要这么做的理由

配置切面

如果是通过注解配置的话,其实 仅仅配置@Aspect 表示当前类是一个切面类,然后在方法上配置各种通知比如:@Before这里讲的是编程 AOP 所以就不多说 注解了

ProxyFactory

纯手动的AOP … spring 底层就是这样的,我基本就是直接复制 源码随便改改就好了… public class ProxyFactoryContext implements ProxyFactoryContextImplements{ public static void main(String[] args) { //创建 代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); // proxyFactory.copyFrom(null); // 如果是 true 则使用 cglib // 如果是 false 则使用 Proxy proxyFactory.setProxyTargetClass(false); proxyFactory.setInterfaces(); // 添加(切面) proxyFactory.addAdvice((MethodBeforeAdvice) (method, args1, target) -> { System.out.println("前置通知"); }); // proxyFactory.addAdvisors(); // 设置 目标 对象 proxyFactory.setTargetSource(new SingletonTargetSource(new ProxyFactoryContext())); proxyFactory.setExposeProxy(true); ProxyFactoryContext proxy = (ProxyFactoryContext) proxyFactory.getProxy(); proxy.log(); System.out.println(proxy.getClass().getName()); } @Override public void log() { System.out.println("我是本体方法"); } }

ProxyFactoryBean

可以从 spring 容器中获取

配置通知

@Component("beforeAdvice") // 实现了 MethodBeforeAdvice 表示当前类是一个 方法级别的 前置操作 public class BeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("before advice."); } }

配置类

@Configuration public class ProxyFactoryConfig { @Bean public ProxyFactoryBean proxyFactoryBean(ProxyFactoryBeanInterface beanInterface) throws Exception { // 继承了: ProxyCreatorSupport ProxyFactory factory = new ProxyFactory(); // 继承了: ProxyCreatorSupport ProxyFactoryBean factoryBean = new ProxyFactoryBean(); //设置要代理的目标类 factoryBean.setTarget(beanInterface); //设置要代理的接口的全限定类名 factoryBean.setProxyInterfaces(new Class[]{ProxyFactoryBeanInterface.class}); //设置切面类的类名称,这里会去 spring 容器中找到 这个 Advice factoryBean.setInterceptorNames("beforeAdvice"); // 这里是直接添加... factoryBean.addAdvice(new MethodBeforeAdvice (){ @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("后置1"); } }); // 如果是 true则使用 cglib // 如果是 false 则使用 Proxy的方式 factoryBean.setProxyTargetClass(true); // 简单来说,你可以 在 代理的目标类 获取到 代理对象 // 这么做有什么好处呢? 例如: A方法 调用B 方法 ,A是增强的但是B不是那此时我们想让B也是增强的如何处理呢 // 那就可以通过 AopContext.currentProxy()获取到当前代理对象然后进行内部调用即可 factoryBean.setExposeProxy(true); return factoryBean; } }

定义目标类

public interface ProxyFactoryBeanInterface { public void add(); public void delete(); } @Component public class ProxyFactoryBeanInterfaceImpl implements ProxyFactoryBeanInterface { @Override public void add() { System.out.println("++++++++++"); } @Override public void delete() { System.out.println("--------------"); // 如果单纯的去调用ADD 会发现不是增强的, // 但是我们想 让 delete 在调用 add()的时候 add 也是被AOP增强的要如何处理呢? ProxyFactoryBeanInterface o =(ProxyFactoryBeanInterface) AopContext.currentProxy(); o.add(); } }

上下文类

@ComponentScan public class ProxyFactoryContext { public static void main(String[] args) { AnnotationConfigApplicationContext value = new AnnotationConfigApplicationContext(ProxyFactoryContext.class); // getBean(value); // getProxyFactoryBean(value); // getBeanByFactoryBean(value); getThreadLocal(value); } private static void getThreadLocal(AnnotationConfigApplicationContext value) { ProxyFactoryBeanInterface bean = (ProxyFactoryBeanInterface) value.getBean("proxyFactoryBean"); bean.delete(); System.out.println(bean.getClass().getName()); } private static void getBeanByFactoryBean(AnnotationConfigApplicationContext value) { ProxyFactoryBeanInterface bean = (ProxyFactoryBeanInterface) value.getBean("proxyFactoryBean"); bean.add(); System.out.println(bean.getClass().getName()); } /** * 通过工厂拿到的Bean * * @param value */ private static void getProxyFactoryBean(AnnotationConfigApplicationContext value) { ProxyFactoryBean bean = value.getBean(ProxyFactoryBean.class); Object object = bean.getObject(); ProxyFactoryBeanInterface anInterface = (ProxyFactoryBeanInterface) object; anInterface.add(); } /** * 从新去获取 Bean了 * * @param value */ private static void getBean(AnnotationConfigApplicationContext value) { ProxyFactoryBeanInterface bean = (ProxyFactoryBeanInterface) value.getBean("proxyFactoryBeanInterfaceImpl"); bean.add(); } }

参考

https://www.jianshu.com/p/b38b1a8cb0a4

最新回复(0)