一 动态代理
动态代理分为JDK动态代理和CGLIB动态代理
jdk动态代理
被代理类(目标类)和代理类必须实现同一个接口,jdk动态代理只能代理实现了接口的类,原因是生成的动态代理类会继承Proxy类,并且实现被代理类实现的接口,而java只支持单继承
核心:反射包下的Proxy类(提供了创建动态代理实例的静态方法)、反射包下的InvocationHandler接口(每个代理角色都会关联一个这个,他的invoke方法等于就是执行生成的动态代理类的实现了了接口的对应方法)
proxy类的创建代理类实例的方法
实例:invoke方法的第一个参数就是代理类的对象(非目标类的对象),第二个参数就是代理类对象要调用的方法,第三个参数是代理类方法的参数
过程:调用代理类的某个方法,会由invocationHandler调用处理器来调用invoke方法执行
CGLIB动态代理
针对没有实现接口的类的代理,采用CGLIB(Code Generation Library)技术。CGLIB是一个基于底层ASM的字节码生成库,由第三方提供,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承被代理类(目标类)的方式实现代理
实例:第一个参数是目标类对象
二 Spring AOP用什么动态代理来实现
测试的demo:
模拟切面around环切记录userService方法的执行时间,查看拿到的具体的userService的对象(代理对象)
可以看到这个userService的代理对象是jdk代理对象
如果我们不让userServiceImpl实现userService接口,并且在serviceImpl上面加注解@service("userService)的话,我们再将demo代码改成如下情况
再次查看我们获取到的这个userService,发现它是一个CGLIB代理对象
总结
spring的AOP使用到了jdk动态代理和CGLIB动态代理,区别在于我们的代理对象是否为接口,如果我们没有继承接口或者不是接口的话就会用CGLIB动态代理,如果实现了接口就会用jdk动态代理。我们可以看见userService对象被代理了,是一个代理对象,至于什么时候被代理,我们从下面的代码开始分析
三 源码流程
从上面的从容器中getBean开始看,至于前面的部分代码请参考spring循环依赖源码,
注意:下面的代码可能会被很多地方调用,而不仅仅是你自己的代码,因此你需要进行断点过滤(条件断点)或者等到你自己的beanName代码开始执行再在后面打断点
getBean->
doGetBean(Object sharedInstance = getSingleton(beanName)) 这一步获取到CGLIB代理对象
-
getSingleton(beanName,allowEarlyReference)
在第一行我们的userService对象已经不空,因此这里是我们要看的点,这里是从一级缓存中获取到我们需要的对象,因此,我们需要看什么时候将代理对象put到一级缓存的,以及什么时候从原生对象变成代理对象的
从doGetBean->
createBean->
-
doCreateBean Object beanInstance = doCreateBean(beanName,mbd,args)在这一行原生的userServiceImpl变成了代理对象,具体变成代理对象的行是下面的initializeBean方法
继续向下走,发现是initializeBean方法的applyBeanPostProcessorsAfterInitialization这个方法将其变成代理对象
继续往下,可以看到红框就是处理我们的生成代理对象的processor
继续往下,看下面的getEarlyBeanReference的wrapIfNecessary方法,发现在下面红框的这一行,原生对象变成了代理对象
继续往下,我们发现了什么时候使用jdk动态代理,什么时候使用CGLIB动态代理
AbstractAutowireCapableBeanFactory# doCreateBean
AbstractAutowireCapableBeanFactory# getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 这里经过一系列的processor,保证instB能够拿到instA的代理对象的引用
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
AbstractAutoProxyCreator# getEarlyBeanReference
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}
AbstractAutoProxyCreator# wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 在这里userServiceImpl原生对象变成了代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
AbstractAutoProxyCreator# createProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
ProxyFactory# getProxy
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
ProxyCreatorSupport# createAopProxy
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
DefaultAopProxyFactory# createAopProxy
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 第一个条件恒为false,第二个条件可以配置,默认为false,第三个条件判断当前对象是否为接口(比如userServiceImpl实现userService的话,userService是一个接口,因此可以走这里)
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
CglibAopProxy# getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}