大前提:该类必须实现了某个接口,其他类使用注解引用该类时,必须基于其实现的接口类型注入,否则注入不成功。
- 方式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动态代理生效。