【问题标题】:SpringBeans and Inheritance results in NoSuchBeanDefinitionExceptionSpringBeans 和继承导致 NoSuchBeanDefinitionException
【发布时间】:2019-10-09 08:22:41
【问题描述】:

所以我基本上有这个设置:

我有一个在 WAS 8.5.5 上运行的应用程序,它使用这个项目的 web-API 将我们的 CRM 同步到 EMS。 我负责创建一个网络前端来维护这些同步。为了显示数据库值,我只是在 html 上打印数据库表。

我已经创建了一个小结构,你会在进入 coden-ps 时理解它。

这个项目的工作流程基本上是轮询同步,并将结果数据收集到数据库中。我的前端负责显示收集到的数据。 为此,我使用 pojo 的子类来对应客户端,因为我的前端能够采用从父类继承的任何类型的网格。

子类继承自父类 Grid:

public class Grid {
    private List<String> columnNames;
    private List<Page> pages; //this are custom pages consisting of a specific amount of tablerows
    private int currentPageIndex;
    private boolean isSortedDescending;

    //Getters and Setters
}

子类是:

历史网格:

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class HistoryGrid extends Grid{
    private HistoryAttributes sortedBy; //this is a enumvalue

    //Getter and Setter
}

和 HistoryDe​​tailGrid:

@Component
public class HistoryDetailGrid extends Grid {
    private long historyEntryId; //to map the details to its Histories
    private HistoryDetailAttributes sortedBy; //this is a enumvalue

    //Getters and Setters

两个网格都代表数据库表,并且是 1:n 关系,每个历史条目都有 n 个历史细节条目。

比我的 Businesslogic 类遵循相同的继承模式:

网格服务:

public abstract class GridService { 
    Grid grid;

    public void nextPage() {
        ... //this needs the grid-variable
    }

    public void lastPage() {
        ... //this needs the grid-variable
    }

    //Getter and Setter

    public abstract void initGrid();
    public abstract void createPages();
    public abstract void filter(Object property, String valueFilteredBy);
    public abstract void sort(Object property, boolean isDescending);
}

HistoryGridService:

@Service
public class HistoryGridService extends GridService {   
    @Autowired
    private HistoryGrid hg;

    @Override
    public void createPages() {
        ...
    }

    @Override
    public void initGrid() {
        ...
    }

    @Override
    public void filter(Object property, String valueFilteredBy) {
        ... 
    }

    @Override
    public void sort(Object property, boolean isDescending) {
        ...
    }

    //Getters and Setters
}

还有 HistoryDe​​tailGridService:

@Service
public class HistoryDetailGridService extends GridService {
    @Autowired
    HistoryDetailGrid hdg;

    public void initGridByCsv() {       
        ...
    }

    @Override
    public void initGrid() {
        ...
    }

    @Override
    public void createPages() {
        ...
    }

    @Override
    public void filter(Object property, String valueFilteredBy) {
        ...
    }

    @Override
    public void sort(Object property, boolean isDescending) {
        ...
    }
}

为了简单起见,我删除了所有不必要的属性和逻辑,无需关注这一点。

在启动我的应用程序时,我遇到了这个异常:

com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0271E: Uncaught init() exception created by servlet [dispatcher] in application [MyProjectEAR]: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'historyGridService': Unsatisfied dependency expressed through field 'grid'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.me.my_project.web.Grid' available: expected single matching bean but found 2: historyDetailGrid,historyGrid
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:171)
    at javax.servlet.GenericServlet.init(GenericServlet.java:161)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:345)
    at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.init(ServletWrapperImpl.java:168)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1369)
    at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:642)
    at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:608)
    at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:426)
    at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
    at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:171)
    at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:904)
    at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:789)
    at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:427)
    at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:719)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1211)
    at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1452)
    at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:641)
    at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:1034)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:795)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl$5.run(ApplicationMgrImpl.java:2279)
    at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5482)
    at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5698)
    at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2284)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:436)
    at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:379)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:127)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$CUInitializer.run(CompositionUnitMgrImpl.java:985)
    at com.ibm.wsspi.runtime.component.WsComponentImpl$_AsynchInitializer.run(WsComponentImpl.java:524)
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.me.my_project.web.Grid' available: expected single matching bean but found 2: historyDetailGrid,historyGrid
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 46 more

该异常基本上是说我的 HistoryGridService 无法注入 Grid,这有点令人困惑,因为 HistoryGridService 不应该知道任何有关网格的信息,因为它使用的是 Grids 子级 -> HistoryGrid。 Springs IoC-Container 也不应该对 Grid 有任何了解,它不是 bean。

那么这个异常是怎么发生的,我该如何解决呢?

我的期望是 HistoryGridService 应该能够注入 HistoryGrid 而不是 Grid。

提前致谢。

编辑 1 @M。 Deinum 的方法

所以我做了这个:

@Service
public class HistoryGridService extends GridService {
    public class Config {
        @Bean
        public HistoryGrid historyGrid() {
            return new HistoryGrid();
        }
    }

    private final HistoryGrid HG;

    public HistoryGridService(HistoryGrid hg) {
        super(hg);
        HG = hg;
    }

    ...
}

请注意,我无法将 hg 设为 final,因为它将在每种方法中更新。

在 GridService 中:

public abstract class GridService {
    private Grid grid;

    public GridService(Grid grid) {
        this.grid = grid;
    }

但是这种方法会导致此异常:

    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:171)
    at javax.servlet.GenericServlet.init(GenericServlet.java:161)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:345)
    at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.init(ServletWrapperImpl.java:168)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1369)
    at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:642)
    at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:608)
    at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:426)
    at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
    at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:171)
    at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:904)
    at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:789)
    at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:427)
    at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:719)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1211)
    at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1452)
    at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:641)
    at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:1034)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:795)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl$5.run(ApplicationMgrImpl.java:2279)
    at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5482)
    at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5698)
    at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
    at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2284)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:436)
    at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:379)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:127)
    at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$CUInitializer.run(CompositionUnitMgrImpl.java:985)
    at com.ibm.wsspi.runtime.component.WsComponentImpl$_AsynchInitializer.run(WsComponentImpl.java:524)
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.me.my_project.services.HistoryDetailGridService$Config': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'historyDetailGridService': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    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:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    ... 46 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'historyDetailGridService': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:347)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    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:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    ... 69 more

编辑 2 修复

关注@M。 Deinum 建议我能够解决这个问题。 两个子类现在都有一个参数化构造函数,它接受 HistoryGrid 或 HistoryDe​​tailGrid 的实例。这些将在创建 bean 时从 IoC-Container 隐式注入。

public abstract class GridService { 
    private final Grid GRID;

    public GridService(Grid grid) {
        GRID = grid;
    }
    ...
}
@Service
public class HistoryDetailGridService extends GridService {
    private final HistoryDetailGrid HDG;

    public HistoryDetailGridService(HistoryDetailGrid hdg) {
        super(hdg);
        HDG = hdg;
    }
    ...
}

【问题讨论】:

  • 您的两个类都是Grid 实例(它们扩展了它),并且由于您的超类需要Grid,它无法完成将依赖项连接到您的基础GridService,因为它找到了2 个遵守成为Grid。修理。从您的字段中删除@Autowired,将它们设为private final 并使用构造函数注入,并调用super(grid) 将其也注入到您的超类中。
  • 我是如何理解的: - 在 GridService 中实现构造函数 -> public GridService(Grid grid) - 从 HistoryGridService.hg 中删除 Autowired - 覆盖 HistoryGridServices 默认构造函数并调用 super(hg) - 还创建一个内部用 Configuration 注释的类有一个用 Bean 注释的 getter,它返回一个新的 HistoryGrid(),但是当删除 Autowired 注释时,HistoryGrid 将如何注入到 HistoryGridService 中?我关注了这个baeldung.com/constructor-injection-in-spring
  • 只需将它添加到构造函数中...由于只有一个构造函数,spring 会检测到它并将其用于自动装配。这样你甚至不需要@Autowired
  • sry 我现在有点困惑,添加什么到哪个构造函数,因为我有两个新的构造函数:GridService(Grid grid) { this.grid = grid } 和 HistoryGridService() { super.(hg) }
  • HistoryGridService(HistoryGrid hg) 应该首先调用super(hg) 然后调用this.hg=hg。其中this.hg 应该是final。超类中的grid 字段也是如此。

标签: spring spring-mvc inversion-of-control ioc-container websphere-8


【解决方案1】:

在这种情况下,Grid 类由两个类(HistoryGrid 和 HistoryDe​​tailGrid)扩展,Spring 将不知道要注入两个实现中的哪一个:在创建时区分 bean 名称需要指定限定符。

--------------------------
public class Grid {
    ......
    ......
    //added this method to show which implementation is invoked
    public void printClassName(){
        System.out.println("In Grid");
    }

}

@Component("historyDetailGrid")
public class HistoryDetailGrid extends Grid {

    ......
    ......
    @Override  
    public void printClassName(){
        System.out.println("Inside historyDetail Grid");
    }
}

@Component("historyGrid")
public class HistoryGrid extends Grid {

    .......
    .......
    @Override  
    public void printClassName(){
        System.out.println("Inside history Grid");
    }
}


public abstract class GridService {
    //Removed grid declaration and get grid object as method param
    public void nextPage(Grid grid) {
    }

    public void lastPage(Grid grid) {
    }

    /**
     * To show which implementation class is invoked from main method
     */
    public abstract void printClassName();

    public abstract void createPages();

    public abstract void filter(Object property, String valueFilteredBy);

    public abstract void sort(Object property, boolean isDescending);
}

@Service("historyDetailGridService")
public class HistoryDetailGridService extends GridService {
    @Autowired
    @Qualifier("historyDetailGrid")
    Grid hdg;

 @Override
    public void printClassName() {
        hdg.printClassName();
    }

 // other abstract methods
  .....
}

@Service("historyGridService")
public class HistoryGridService extends GridService {
    @Autowired
    @Qualifier("historyGrid")
    private Grid hg;

   @Override
    public void printClassName() {
        hg.printClassName();
    }

 // other abstract methods
  .....
}

@SpringBootApplication
@ComponentScan({"com.*"})
public class Main {
    @Autowired
    @Qualifier("historyDetailGridService")
    GridService historyDetailGridService;

    @Autowired
    @Qualifier("historyGridService")
    GridService historyGridService;

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);

    }

    @PostConstruct
    public void printClasses(){
        historyGridService.printClassName();
        historyDetailGridService.printClassName();
    }

}

----------------
output will be 
Inside history Grid
Inside historyDetail Grid
2019-10-09 21:34:31.356  INFO 3235 --- [           main] com.service.Main                         : Started Main in 1.439 seconds (JVM running for 1.791)
-----------------

【讨论】:

    猜你喜欢
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    相关资源
    最近更新 更多