问题
1) Below is the small project I have where I do want logging with SpringAOP. Using spring-aop-4.1.6.RELEASE.jar and below is LoggingAspect.java with few point cuts.
package com.myprj.aop.aspect;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
private final Log log = LogFactory.getLog(getClass());
@Before("logForAllMethods()") // after advice with name pointcut that declared as name logForAllMethods()
public void beforeAdviceForAllMethods(JoinPoint jp) throws Throwable {
Object clazz = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
log.info("Before Entering to Class " + clazz + " With Method Name " + methodName);
// getting method parameter name
Object[] obj = jp.getArgs();
for (Object o : obj) {
if (o != null) {
log.info("Parameter Name..." + o.toString());
} else {
log.info("");
}
}
}
@After("logForAllMethods()") // after advice with name pointcut that declared as name logForAllMethods()
public void afterAdviceForAllMethods(JoinPoint jp) throws Throwable {
Object clazz = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
log.info("After Entring to Method " + methodName + " in Calss " + clazz);
}
@Pointcut("execution(public * *(..))") // enable for all public methods
public void logForAllMethods() {
}
}
Also below is the sample Service and ServiceImpl classes I have
package com.myprj.aop.service;
public interface TransferService {
void transfer(String accountA, String accountB, Long amount);
Double checkBalance(String account);
Long withdrawal(String account, Long amount);
void diposite(String account, Long amount);
}
package com.myprj.aop.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class TransferServiceImpl implements TransferService {
@Autowired
@Qualifier("finalClass")
FinalClass finalClass;
@Override
public void transfer(String accountA, String accountB, Long amount) {
System.out.println(amount + " Amount has been tranfered from " + accountA + " to " + accountB);
}
@Override
public Double checkBalance(String account) {
System.out.println("Available balance: 50000");
finalClass.toString();
return new Double(50000);
}
@Override
public Long withdrawal(String account, Long amount) {
System.out.println("Withdrawal amount: " + amount);
finalClass.toString();
return amount;
}
@Override
public void diposite(String account, Long amount) {
System.out.println(amount + " Amount has been diposited to " + account);
finalClass.toString();
}
}
Also, I have a Singleton class where few methods need to be invoked like below.
package com.myprj.aop.service;
public class FinalClass {
private String constructorParam;
private FinalClass(String param) {
constructorParam = param;
}
@Override
public String toString() {
System.out.println(constructorParam);
return constructorParam;
}
}
Below is applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.myprj.aop.*" />
<bean id="finalClass" class="com.myprj.aop.service.FinalClass">
<constructor-arg value="constructorArg"></constructor-arg>
</bean>
<aop:aspectj-autoproxy/>
</beans>
Main class:
package com.myprj.aop.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.myprj.aop.config.AppConfig;
import com.myprj.aop.service.TransferService;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
TransferService transferService = applicationContext.getBean(TransferService.class);
transferService.transfer("accountA", "accountB", 50000l);
transferService.checkBalance("accountA");
transferService.diposite("accountA", 50000l);
transferService.withdrawal("accountB", 40000l);
//applicationContext.close();
}
}
Get below error
WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transferServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.myprj.aop.test.Main.main(Main.java:19)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 13 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 15 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
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:447)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:333)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 24 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
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)
... 31 more
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transferServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.myprj.aop.test.Main.main(Main.java:19)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.myprj.aop.service.FinalClass com.myprj.aop.service.TransferServiceImpl.finalClass; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 13 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'finalClass' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 15 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.myprj.aop.service.FinalClass]: 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 com.myprj.aop.service.FinalClass
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:447)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:333)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 24 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class com.myprj.aop.service.FinalClass
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)
... 31 more
The inject injection is failing. After googling, many have suggested setter based injection. But when singleton class is created more operations are done in actual code. Also as per below link, this has been fixed in Spring 4.0. What is wrong with my code?
回答1:
as your exception says itself
No visible constructors in class com.myprj.aop.service.FinalClass
change your private constructor to public.
回答2:
It tells you what the problem is: No visible constructors in class com.myprj.aop.service.FinalClass
.
There is no way for spring to "guess" which static getInstance() method to call to instantiate the singleton.
You must provide a public empty c'tor for it.
If you use spring accross your application, you can define FinalClass as a singleton using the @Scope property.
来源:https://stackoverflow.com/questions/52811994/issue-with-spring-aop-and-final-class-throwing-could-not-generate-cglib-subclas