好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

基于spring同名bean覆盖问题的解决

spring同名bean覆盖问题

默认情况下,spring在处理同一个ApplicationContext中名称相同的bean时

分为两种情况处理

1、如果两个bean是在同一个配置文件中,那么spring会报错。

2、如果两个bean是在不同的配置文件中,默认情况下,spring会覆盖先前的bean。

在配置文件很多时,如果在启动时,对于同名的bean加载没有异常信息,出现问题后会比较难以定位。

在spring中,处理容器的元数据信息时,默认使用DefaultListableBeanFactory类,该类中有个属性:allowBeanDefinitionOverriding,默认情况下为true,即允许重名的bean可以被覆盖。

还好,spring有办法对改属性赋值。

重写ContextLoaderListener,对于web应用,容器类型为XmlWebApplicationContext,在该类中设置allowBeanDefinitionOverriding为false,然后在spring启动时,碰到同名bean就会抛出异常。

案例如下

?

1

2

3

4

5

6

7

8

9

public class TradeContextLoaderListener extends ContextLoaderListener {

  @Override

  protected void customizeContext(ServletContext servletContext,

    ConfigurableWebApplicationContext applicationContext) {

   super .customizeContext(servletContext, applicationContext);

   XmlWebApplicationContext context = (XmlWebApplicationContext) applicationContext;

   context.setAllowBeanDefinitionOverriding( false );

  }

}

配置web.xml:

?

1

2

3

4

< listener >

  < description >spring监听器</ description >

  < listener-class >com.***.trade.system.web.util.TradeContextLoaderListener</ listener-class >

</ listener >

spring 子类覆盖父类中注入的bean

我们在设计程序框架的时候,会设计一个抽象基类,子类继承这个基类,共有的方法放到基类中去,使用spring后使代码变的很简单,现在遇到的问题是在基类中注入bean后,子类不可能都会是有这个bean,那么需要考虑到子类需要覆盖或者说重新注入个性化的bean

有三种方法来实现这个效果,以下是一种方法,如下面代码:

抽象基类

?

1

2

3

4

public abstract class AbstractNameService

{

  public abstract String getname();

}

两个实现类:

?

1

2

3

4

5

6

7

8

9

@Service ( "firstNameService" )

public class FirstNameService extends AbstractNameService

{

  @Override

  public String getname()

  {

   return "FirstName" ;

  }

}

?

1

2

3

4

5

6

7

8

9

@Service ( "nameService" )

public class NameService extends AbstractNameService

{

  @Override

  public String getname()

  {

   return "Name" ;

  }

}

另外一个抽象基类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public abstract class AbstractService

{

  protected AbstractNameService nameService;

  public String getName()

  {

   return nameService.getname();

  }

  public AbstractNameService getService()

  {

   return nameService;

  }

  <span style= "color:#ff9966;" > @Resource (name = "nameService" )</span>

  public void setService(AbstractNameService nameService)

  {

   this .nameService = nameService;

  }

}

实现类:

?

1

2

3

4

5

6

7

8

9

10

@Service ( "getNameService" )

public class GetNameService extends AbstractService

{

  <span style= "color:#ff9900;" > @Resource (name = "firstNameService" )</span>

  @Override

  public void setService(AbstractNameService nameService)

  {

   this .nameService = nameService;

  }

}

controller

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Controller

public class UnionpayQuickPayDSMVC

{

  @Resource

  private AbstractService getNameService;

  @RequestMapping (value = "/*" , method = RequestMethod.GET)

  public void execute(HttpServletRequest request, HttpServletResponse response)

  {

   try

   {

    response.getWriter().write(getNameService.getName());

   }

   catch (IOException e)

   {

    System.out.println(e);

   }

  }

}

在applicationContext.xml和springmvc的配置文件只需要添加一个包<context:component-scan/>标签就行了

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/ado1986/article/details/49334791

查看更多关于基于spring同名bean覆盖问题的解决的详细内容...

  阅读:33次