基於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就會拋出異常。

案例如下

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:

 <listener>
  <description>spring監聽器</description>
  <listener-class>com.***.trade.system.web.util.TradeContextLoaderListener</listener-class>
 </listener>

spring 子類覆蓋父類中註入的bean

我們在設計程序框架的時候,會設計一個抽象基類,子類繼承這個基類,共有的方法放到基類中去,使用spring後使代碼變的很簡單,現在遇到的問題是在基類中註入bean後,子類不可能都會是有這個bean,那麼需要考慮到子類需要覆蓋或者說重新註入個性化的bean

有三種方法來實現這個效果,以下是一種方法,如下面代碼:

抽象基類

public abstract class AbstractNameService
{
 public abstract String getname();
}

兩個實現類:

@Service("firstNameService")
public class FirstNameService extends AbstractNameService
{ 
 @Override
 public String getname()
 {
  return "FirstName";
 } 
}
@Service("nameService")
public class NameService extends AbstractNameService
{ 
 @Override
 public String getname()
 {
  return "Name";
 } 
}

另外一個抽象基類

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;
 } 
}

實現類:

@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

@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/>標簽就行瞭

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: