使用单例模式AOP时,注入自动连接的依赖项失败

时间:2014-10-30 13:07:19

标签: java spring dependency-injection spring-aop

我有一个使用Singleton模式的CommandService类,因此它有一个私有构造函数。在使用AOP之前,我使用getInstance()方法返回Application.java中的bean,如下所示:

@Configuration
@EnableAutoConfiguration
@ComponentScan({"hello","wodinow.weixin.jaskey"})
public class Application {

public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(Application.class, args);

    LogUtil.info("Beans provided by Spring Boot:");
    String[] beanNames = ctx.getBeanDefinitionNames();
    Arrays.sort(beanNames);
    for (String beanName : beanNames) {
        LogUtil.info(beanName);
    }
    LogUtil.info("Application Boots completes!");
}

//here I use a getInstance() to return that bean 
@Bean  
public CommandService commandService(){
    return CommandService.getInstance();
}

我的Controller使用此类,需要Spring自动连接它。

@Controller
public class CoreController {

    @Autowired
    private CommandService commandService;
    ...
}

在我介绍AOP之前,这很好用。

在我使用这样的东西之后:

@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* wodinow.weixin.jaskey..*.*(..))")
    private void debug_log(){};

    @AfterReturning("debug_log()")
    public void debug(JoinPoint joinPoint){
        LogUtil.debug("returns from "+joinPoint.getSignature());
    }

}

运行Application.java时,我的应用程序失败

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coreController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private wodinow.weixin.jaskey.service.CommandService wodinow.weixin.jaskey.co.CoreController.commandService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private wodinow.weixin.jaskey.service.RoomService wodinow.weixin.jaskey.service.CommandService.roomService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomService' defined in class wodinow.weixin.jaskey.config.Application: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class wodinow.weixin.jaskey.service.RoomService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
    at wodinow.weixin.jaskey.config.Application.main(Application.java:22)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private wodinow.weixin.jaskey.service.CommandService wodinow.weixin.jaskey.co.CoreController.commandService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private wodinow.weixin.jaskey.service.RoomService wodinow.weixin.jaskey.service.CommandService.roomService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomService' defined in class wodinow.weixin.jaskey.config.Application: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class wodinow.weixin.jaskey.service.RoomService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 16 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private wodinow.weixin.jaskey.service.RoomService wodinow.weixin.jaskey.service.CommandService.roomService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomService' defined in class wodinow.weixin.jaskey.config.Application: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class wodinow.weixin.jaskey.service.RoomService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1081)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1006)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
    ... 18 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private wodinow.weixin.jaskey.service.RoomService wodinow.weixin.jaskey.service.CommandService.roomService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomService' defined in class wodinow.weixin.jaskey.config.Application: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class wodinow.weixin.jaskey.service.RoomService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 29 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roomService' defined in class wodinow.weixin.jaskey.config.Application: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class wodinow.weixin.jaskey.service.RoomService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:548)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1081)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1006)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
    ... 31 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class wodinow.weixin.jaskey.service.RoomService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:445)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:331)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:291)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1573)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)
    ... 40 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class wodinow.weixin.jaskey.service.RoomService
    at org.springframework.cglib.proxy.Enhancer.filterConstructors(Enhancer.java:531)
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:448)
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
    ... 47 more

我的CommandService就像:

public class CommandService {

private static CommandService instance = new CommandService();

    @Autowired
    private RoomService roomService;//this is a class uses the same singleton patterns as `CommandService` does, and it has the same problem.

    //private constructor
    public CommandService() {}

    // singleton patterns
    public static CommandService getInstance() {
        return instance;
    }

    ...something else
 }

我知道spring默认情况下每次只需要返回一个实例,但是如果我确实需要构造函数是私有的,以防其他人使用该构造函数。

谢谢!

0 个答案:

没有答案