使用自动装配从实现类设置抽象类的属性

时间:2019-04-03 00:39:08

标签: java spring-boot groovy dependency-injection

我试图在实现类(Service)的抽象类中设置受保护属性的属性。我在实现类中使用@Autowired注释并使用了setter注释。我正在用Groovy对此进行编码,如果需要的话,它在后台实现getter和setter。当我尝试运行此代码时,会创建一条错误消息,指示发生了StackOverFlow错误:

""2019-04-02 19:53:57 [restartedMain] ERROR o.s.boot.SpringApplication - Application startup failed
"org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:139)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:124)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.SpringApplication$run.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
    at gov.epa.esml.WarInitializerApplication.main(WarInitializerApplication.groovy:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:138)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:87)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:554)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:179)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:166)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:136)
    ... 15 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sessionVariableFilter': Unsatisfied dependency expressed through field 'myEmsService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEmsService': Injection of autowired dependencies failed; nested exception is java.lang.StackOverflowError
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1269)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:234)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:182)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:177)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:159)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:80)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:252)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:225)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:90)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:215)
    at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:55)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5267)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1423)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1413)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEmsService': Injection of autowired dependencies failed; nested exception is java.lang.StackOverflowError
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:370)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1269)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1136)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583)
    ... 27 common frames omitted
Caused by: java.lang.StackOverflowError: null
    at java.lang.Exception.<init>(Exception.java:102)
    at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
    at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
    at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2726)
    at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3785)
    at gov.epa.esml.table.ARichTableService.setProperty(ARichTableService.groovy)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setGroovyObjectProperty(ScriptBytecodeAdapter.java:545)
    at gov.epa.esml.myEms.service.MyEmsService.setConverter(MyEmsService.groovy:38)
    at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
....
@Service("myEmsService")
class MyEmsService extends ARichTableService implements IMyEmsService {

    @Autowired
    EmRepository emRepository
    @Autowired
    void setDataService(IMyEmsDAO dataService) {
        this.dataService = dataService
    }

    @Autowired
    @Qualifier("emFieldsRenderer")
    void setConverter(AClassFieldsRenderer converter) {
        this.converter = converter
    }

    @Override
    TableData getTableData(HttpServletRequest request, Collection<ColumnHeader> headers,
                           Integer offset, Integer pageSize, Collection<ADataFilter> filters,
                           Collection<ColSort> orderBy) throws Exception {

        Collection<Object> data
        try {
            data = dataService.getTableData(headers, offset, pageSize, filters, orderBy);
            Collection<Object> ems = new ArrayList<Object>()
            for (Object d : data) {
                ems.add(d)
            }
            data = ems
        } //This happens when subqueries returns empty sets.
        catch (SQLGrammarException e) {
            data = new ArrayList<Object>()
        }

        TableData formatedData = new TableData()
        formatedData.setHeaders((ArrayList<ColumnHeader>) headers)

        for (Object o : data) {
            Object d = converter.convert(o, headers)
            formatedData.addData((ArrayList<String>) d)
        }

        return formatedData
    }


    List<Em> getRelatedIds(Integer myId) {
        emRepository.findByParentId(myId)
    }
}
abstract class ARichTableService implements IRichTableService {

    protected AClassFieldsRenderer converter

    protected IRichTableDAO dataService

    @Override
    TableData getTableData(HttpServletRequest request, Collection<ColumnHeader> headers,
                           Integer offset, Integer pageSize, Collection<ADataFilter> filters,
                           Collection<ColSort> orderBy) throws Exception {

        Collection<Object> data = null
        try {
            data = dataService.getTableData(headers, offset, pageSize, filters, orderBy)
        }
        //This happens when subqueries returns empty sets.
        catch (SQLGrammarException e) {
            data = new ArrayList<Object>()
        }

        TableData formatedData = new TableData()
        formatedData.headers = (ArrayList<ColumnHeader>) headers

        for (Object o : data) {
            Object d = converter.convert(o, headers)
            formatedData.addData((ArrayList<String>) d)
        }

        return formatedData
    }

    Long getTotalRows(Collection<ADataFilter> filters, Integer pageSize) throws Exception {
        return (dataService.getTotalRows(filters))
    }
}
interface IMyEmsService extends IRichTableService {

    List<Em> getRelatedIds(Integer myId)

}

我不确定代码的哪一部分正在创建该代码,或者是否可以这种格式进行注入?

1 个答案:

答案 0 :(得分:2)

this.converter =很可能试图在幕后致电this.setConverter。理想的方法是转向构造函数注入(这也消除了对@Autowired的需求),但作为立即解决方案,请尝试使用direct field access代替:

@Autowired
void setConverter(AClassFieldsRenderer converter) {
    this.@converter = converter
}