1.问题的描述:springBoot 的版本1.5.9.RELEASE 对应spring的版本4.3.11.RELEASE javamelody-spring-boot-starter的版本是1.71.0,这是此次问题出现环境。
在本地启动的时候报 could not be injected because it is a JDK dynamic proxy,字面的意思就是@Autowired 注入的类无法注入,因为类型不匹配,然后错误的提示解 Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching. 大致就是说使用引入接口或proxyTargetClass=true
但按照提示的处理,报错还是一样,导致项目在本地启动不起来,本地都起不来,还开发个毛线
2.通过一段漫长的百度,这里的问题大致涉及到了spring Aop。spring 默认使用的jdk代理,即基于接口的代理,而使用proxyTargetClass=true的约束,可以强制使用cglib基于类的代理,从Spring 3.2开始,不再需要将CGLIB添加到项目类路径中,
于是早项目的启动类上加上@EnableAspectJAutoProxy(proxyTargetClass = true) 。同样解决不了问题
3.大致分析,既然是由于在代理的时候使用jdk代理而导致的,那么我使用@EnableAspectJAutoProxy(proxyTargetClass = true)来使用cglib来代理,为什么问题没有解决问题呢?难道是是proxyTargetClass = true 的注解没有启作用,于是必须好好的看看@EnableAspectJAutoProxy(proxyTargetClass = true) 这个注解大致能干些什么。
4.源码的解释如下
org.springframework.context.annotation.EnableAspectJAutoProxy
@Target(value={TYPE})
@Retention(value=RUNTIME)
@Documented
@Import(value={AspectJAutoProxyRegistrar.class})
Enables support for handling components marked with AspectJ's @Aspect annotation, similar to functionality found in Spring's <aop:aspectj-autoproxy> XML element. To be used on @Configuration classes as follows:
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
@Bean
public FooService fooService() {
return new FooService();
}
@Bean
public MyAspect myAspect() {
return new MyAspect();
}
}
Where FooService is a typical POJO component and MyAspect is an @Aspect-style aspect: public class FooService {
// various methods
}
@Aspect
public class MyAspect {
@Before("execution(* FooService+.*(..))")
public void advice() {
// advise FooService methods as appropriate
}
}
In the scenario above, @EnableAspectJAutoProxy ensures that MyAspect will be properly processed and that FooService will be proxied mixing in the advice that it contributes.
Users can control the type of proxy that gets created for FooService using the proxyTargetClass() attribute. The following enables CGLIB-style 'subclass' proxies as opposed to the default interface-based JDK proxy approach.
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class AppConfig {
// ...
}
Note that @Aspect beans may be component-scanned like any other. Simply mark the aspect with both @Aspect and @Component:
package com.foo;
@Component
public class FooService { ... }
@Aspect
@Component
public class MyAspect { ... }
Then use the @ComponentScan annotation to pick both up: @Configuration
@ComponentScan("com.foo")
@EnableAspectJAutoProxy
public class AppConfig {
// no explicit @Bean definitions required
}
Since:3.1Author:Chris BeamsJuergen HoellerSee Also:org.aspectj.lang.annotation.Aspect
大致是说使用@Aspect的风格建立在普通的component切面,然后在别的地方使用这个component就会注入的这个组件的代理,proxyTargetClass = true可以控制怎么生成生成这个代理,是以jdk的方式还是cglib的方式,
5.抛出一个新的问题,比如@Autowired 引入的时候什么是注入代理类,什么时候注入普通的类,他这个类中的方法为切点或者使用了类似@Transaction注解的时候会注入代理类,在没有任何方法加强的时候就注入普通的类本身,详细请参考
https://www.cnblogs.com/zcmzex/p/8822509.html 和 https://blog.csdn.net/c_unclezhang/article/details/78769426
6.javamelody是对javaEE应用监控,包括方法的执行时间,整体的性能的等等,那自然是用到了aop为了验证,去掉javamelody的依赖与不去掉javamelody的依赖
有javamelody依赖
去掉javamelody依赖
以接口的方式注入