天天看点

springboot(2.1.1.RELEASE)启用jdk动态代理(默认启用cglib)的方法

大前提:该类必须实现了某个接口,其他类使用注解引用该类时,必须基于其实现的接口类型注入,否则注入不成功。

  • 方式1,启动类上注解如下设置
@SpringBootApplication(exclude = { AopAutoConfiguration.class})
@EnableTransactionManagement
           
  • 方式2,配置文件如下设置
spring:
    aop:
      proxy-target-class: false
           

原因分析:

  • AopAutoConfiguration.class源码
//作为配置类注入
@Configuration 
//当类路劲下存在以上这些类,继续向下判断
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,
		AnnotatedElement.class })  
//当配置中存在以上配置信息,但不是必须要显式的配置,没有也可以
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) 
public class AopAutoConfiguration {
     //作为配置类注入
	@Configuration 
     //开启动态代理(false时为jdk动态代理)
	@EnableAspectJAutoProxy(proxyTargetClass = false) 
     //当配置中存在以上配置信息,必须要显式的配置,没有不成立
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false) 
	public static class JdkDynamicAutoProxyConfiguration {

	}
     //作为配置类注入
	@Configuration 
    //开启动态代理(true时为cglib动态代理)
	@EnableAspectJAutoProxy(proxyTargetClass = true) 
     //当配置中存在以上配置信息,但不是必须要显式的配置,没有也可以
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
	public static class CglibAutoProxyConfiguration {

	}

}
           
  • EnableTransactionManagement注解源码
               
​//可注解的位置
@Target(ElementType.TYPE)
//生效的阶段
@Retention(RetentionPolicy.RUNTIME)
@Documented
//注入以下类
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
    
    //默认false时jdk动态代理,设置为true时为cglib动态代理
	boolean proxyTargetClass() default false;
    //默认代理模式jdk本身自带的代理模式,可以选择为AspectJ
	AdviceMode mode() default AdviceMode.PROXY;
    //加载的顺序号
	int order() default Ordered.LOWEST_PRECEDENCE;

}

​
           
  •  TransactionAutoConfiguration源码
@Configuration
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
		DataSourceTransactionManagerAutoConfiguration.class,
		Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public TransactionManagerCustomizers platformTransactionManagerCustomizers(
			ObjectProvider<PlatformTransactionManagerCustomizer<?>> customizers) {
		return new TransactionManagerCustomizers(
				customizers.orderedStream().collect(Collectors.toList()));
	}

	@Configuration
	@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
	public static class TransactionTemplateConfiguration {

		private final PlatformTransactionManager transactionManager;

		public TransactionTemplateConfiguration(
				PlatformTransactionManager transactionManager) {
			this.transactionManager = transactionManager;
		}

		@Bean
		@ConditionalOnMissingBean
		public TransactionTemplate transactionTemplate() {
			return new TransactionTemplate(this.transactionManager);
		}

	}

	@Configuration
	@ConditionalOnBean(PlatformTransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {

		@Configuration
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration
		@EnableTransactionManagement(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

	}

}
           

方式1去排除掉AopAutoConfiguration配置类不加载,同时显示的配置了EnableTransactionManagement注解,就能使aop动态代理设置成jdk动态代理模式。

方式2在配置文件中配置了动态代理的模式为jdk动态代理,整个项目的启动过程总会先加载AopAutoConfiguration配置类,之后才会加载TransactionAutoConfiguration配置类,这个是因为spring.factories这个配置文件中AopAutoConfiguration的出现顺序比TransactionAutoConfiguration早得多,这个是springboot的自动配置jar包下的一个文件,AopAutoConfiguration和TransactionAutoConfiguration这两个类都会因为配置文件中配置了满足设置aop方式为jdk动态代理的配置信息而分别先后设置aop动态代理模式为jdk动态代理,以致设置jdk动态代理生效。

继续阅读