Spring繁华的AOP王国---第二讲
2023-09-14 09:02:33 时间
Spring繁华的AOP王国---第二讲
Spring AOP的织入
如何与ProxyFactory打交道
public interface ITask {
void excute();
}
public class MockTask implements ITask{
@Override
public void excute() {
System.out.println("task excuted!");
}
}
public class PerformanceMethodInterceptor implements MethodInterceptor {
@Nullable
@Override
public Object invoke(@Nonnull MethodInvocation methodInvocation) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("方法执行前...");
Thread.sleep(1000);
Object proceed = methodInvocation.proceed();
Thread.sleep(1000);
System.out.println("方法执行后");
long end = System.currentTimeMillis();
System.out.println("方法执行总耗时: "+String.valueOf(end-start));
return proceed;
}
}
1.基于接口的代理
MockTask task=new MockTask();
ProxyFactory weaver=new ProxyFactory(task);
weaver.setInterfaces(ITask.class);
NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();
advisor.setMappedName("excute");
advisor.setAdvice(new PerformanceMethodInterceptor());
weaver.addAdvisor(advisor);
ITask proxyObject= (ITask) weaver.getProxy();
proxyObject.excute();
MockTask task=new MockTask();
ProxyFactory weaver=new ProxyFactory(task);
NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();
advisor.setMappedName("excute");
advisor.setAdvice(new PerformanceMethodInterceptor());
weaver.addAdvisor(advisor);
ITask proxyObject= (ITask) weaver.getProxy();
proxyObject.excute();
2.基于类的代理
public class MockTask {
public void excute() {
System.out.println("task excuted!");
}
}
MockTask task=new MockTask();
ProxyFactory weaver=new ProxyFactory(task);
NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();
advisor.setMappedName("excute");
advisor.setAdvice(new PerformanceMethodInterceptor());
weaver.addAdvisor(advisor);
MockTask proxy = (MockTask)weaver.getProxy();
proxy.excute();
System.out.println(proxy.getClass());
3.Introduction的织入
看清ProxyFactory的本质
public interface AopProxy {
Object getProxy();
Object getProxy(@Nullable ClassLoader var1);
}
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport var1) throws AopConfigException;
}
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
public DefaultAopProxyFactory() {
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
}
}
ProxyConfig
public class ProxyConfig implements Serializable {
private static final long serialVersionUID = -8409359707199703185L;
private boolean proxyTargetClass = false;
private boolean optimize = false;
boolean opaque = false;
boolean exposeProxy = false;
private boolean frozen = false;
....
}
Advised
public interface Advised extends TargetClassAware {
boolean isFrozen();
boolean isProxyTargetClass();
Class<?>[] getProxiedInterfaces();
boolean isInterfaceProxied(Class<?> var1);
void setTargetSource(TargetSource var1);
TargetSource getTargetSource();
void setExposeProxy(boolean var1);
boolean isExposeProxy();
void setPreFiltered(boolean var1);
boolean isPreFiltered();
Advisor[] getAdvisors();
default int getAdvisorCount() {
return this.getAdvisors().length;
}
void addAdvisor(Advisor var1) throws AopConfigException;
void addAdvisor(int var1, Advisor var2) throws AopConfigException;
boolean removeAdvisor(Advisor var1);
void removeAdvisor(int var1) throws AopConfigException;
int indexOf(Advisor var1);
boolean replaceAdvisor(Advisor var1, Advisor var2) throws AopConfigException;
void addAdvice(Advice var1) throws AopConfigException;
void addAdvice(int var1, Advice var2) throws AopConfigException;
boolean removeAdvice(Advice var1);
int indexOf(Advice var1);
String toProxyConfigString();
}
AdvisedSupport
ProxyFactory,AopProxy,AdvisedSupport与ProxyFactory的关系
小结
上面的图只是画了一个大概的联系,大家再结合上面的文件好好理解一下
ProxyCreatorSupport内部拥有一个AopProxyFactory的对象实例,但是获取AopProxy的时候,是通过AopProxyFactory 的createAopProxy方法中传入自身实例ProxyCreatorSupport,来得到一个指定的AopProxy的,通过AopProxy 我们就可以获取到被代理后的对象
之说以传入自身,是因为ProxyCreatorSupport实现了AdvisedSupport,AdvisedSupport又实现了Advised接口,可以因此来获取到被代理对象实例和横切逻辑
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
private final List<AdvisedSupportListener> listeners = new ArrayList();
private boolean active = false;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
public ProxyCreatorSupport(AopProxyFactory aopProxyFactory) {
Assert.notNull(aopProxyFactory, "AopProxyFactory must not be null");
this.aopProxyFactory = aopProxyFactory;
}
....
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
return this.getAopProxyFactory().createAopProxy(this);
}
容器中的织入器—ProxyFactoryBean
ProxyFactoryBean的本质
@Nullable
public Object getObject() throws BeansException {
this.initializeAdvisorChain();
if (this.isSingleton()) {
return this.getSingletonInstance();
} else {
if (this.targetName == null) {
this.logger.info("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
}
return this.newPrototypeInstance();
}
}
ProxyFactoryBean的使用
加快织入的自动化进程
使用自动代理的实现机制
可用的AutoProxyCreator
需要明确一点,既然我们使用了自动代理来自动为容器中符合条件的bean生成代理对象,那么我们只需要在配置文件中指定切入点和advice即可了
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
扩展AutoProxyCreator
TargetSource
可用的targetSource实现类
SingletonTargetSource
PrototypeTargetSource
HotSwappableTargetSource
CommonsPool2TargetSource
ThreadLocalTargetSource
自定义TargetSource
public interface TargetSource extends TargetClassAware {
@Nullable
Class<?> getTargetClass();
boolean isStatic();
@Nullable
Object getTarget() throws Exception;
void releaseTarget(Object var1) throws Exception;
}
相关文章
- spring boot 使用mybatis-generator
- spring学习笔记(13)基于Schema配置AOP详解
- 18-spring学习-AOP深入操作
- [Spring学习笔记 5 ] Spring AOP 详解1
- [Spring学习笔记 4 ] AOP 概念原理以及java动态代理
- spring boot: 从配置文件中读取数据的常用方法(spring boot 2.3.4)
- spring boot: filter/interceptor/aop在获取request/method参数上的区别(spring boot 2.3.1)
- Spring AOP源码分析(六)Spring AOP配置的背后
- spring boot的actuator
- 深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存
- spring bean的加载
- spring aop JointPoint类
- Spring AOP编程-aspectJ代理方式选择
- Spring 学习 3- AOP
- Spring学习13-中IOC(工厂模式)和AOP(代理模式)的详细解释
- Spring读源码系列之AOP--05---aop常用工具类学习
- Spring读源码系列之AOP--02---aop基本概念扫盲---下
- 不一样的视角来学习Spring源码之AOP---中
- Spring 中基于 AOP 的 XML操作方式
- Spring的AOP理解
- Spring AOP
- 解决com.alibaba.fastjson.JSONException: write javaBean error问题以及解决Spring Boot加入Shiro导致spring aop失效的问题
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring的核心之IoC容器创建对象
- 011-Spring aop 002-核心说明-切点PointCut、通知Advice、切面Advisor
- 说明反转控制(IOC)和面向方向编程(AOP)在spring中的应用