上篇讲了先获取匹配的通知器,其实也叫做拦截器,准备代理,这篇我们就看看是什么做的。
进行代理工厂的创建,然后判断是否需要设置proxyTargetClass
,以便于后面决定是不是要进行JDK
动态代理还是CGLIB
的动态代理,然后把通知器advisors
包装下,加入到代理工厂,获取代理对象。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
//给bean定义设置暴露属性
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);//复制配置信息
// proxyTargetClass=false的话
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {//查看是否有PRESERVE_TARGET_CLASS_ATTRIBUTE属性,有的话就要设置true
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());
}
其实就是设置他的原来的类型。
static void exposeTargetClass(
ConfigurableListableBeanFactory beanFactory, @Nullable String beanName, Class<?> targetClass) {
if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
beanFactory.getMergedBeanDefinition(beanName).setAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE, targetClass);
}
}
其实就是判断他有没有PRESERVE_TARGET_CLASS_ATTRIBUTE
属性,有的话就要设置ProxyTargetClass=true
。
protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
}
public static boolean shouldProxyTargetClass(
ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {
if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
}
return false;
}
判断他的接口,是不是需要设置ProxyTargetClass=true
,判断他的接口不是内部的回调接口和内部语言接口,就添加接口,否则就设置ProxyTargetClass=true
。
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;//用接口代理,也就是JDK
break;
}
}
if (hasReasonableProxyInterface) {//有接口
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {//没接口就设置true
proxyFactory.setProxyTargetClass(true);
}
}
是不是内部的一些接口。
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
是不是内部语言的一些接口。
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}
添加接口:
public void addInterface(Class<?> intf) {
Assert.notNull(intf, "Interface must not be null");
if (!intf.isInterface()) {
throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");
}
if (!this.interfaces.contains(intf)) {
this.interfaces.add(intf);
adviceChanged();
}
}
添加了接口要有adviceChanged
通知,不过一般我们没用到这个。
@Override
protected void adviceChanged() {
super.adviceChanged();//清除缓存
synchronized (this) {
if (this.active) {
for (AdvisedSupportListener listener : this.listeners) {
listener.adviceChanged(this);
}
}
}
}
先创建AopProxy
代理,然后获取代理。
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
创建AOP
代理,如果激活了,就需要有激活通知,我们也也不太用到:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
激活通知,跟前面的添加接口的通知一样,都是给AdvisedSupportListener
通知。:
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
这个才是真正创建代理,判断一些列条件,有自定义的接口的就会创建JDK
代理,否则就是CGLIB
:
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
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)) {//有接口或者是proxy类型的用JDK
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);//用CGLIB
}
else {
return new JdkDynamicAopProxy(config);//用JDK
}
}
这个就是说如果存在一个接口,还是SpringProxy
类型的,就返回true
,否则就是false
,我们自定义的肯定是false
,如果没接口也是false
。
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
如果是JDK
的动态代理,就是我们熟悉的Proxy.newProxyInstance
,不过这里调用前还做了一些处理。
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);//生成代理
}
后面我们继续来说这个处理吧。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。