前言
- 编程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
本文详细解析了Spring框架中的AOP(面向切面编程)原理,包括如何通过编程方式配置切面、使用ProxyFactory和ProxyFactoryBean创建代理对象,以及如何在Spring环境中实现方法级别的前置和后置通知。
3524

被折叠的 条评论
为什么被折叠?



