Spring中單例bean訪問非單例bean的兩種方式

第一種方式:方法注入
方法注入在Spring中是很少用的,主要應用是, 對象中可能定義了一個受保護的抽象方法,而容器可能在運行時實現他以返回由容器查詢得到的對象。
方法注入的最好用途之一就是處理單態、無狀態對象需要調用非單態、有狀態或者非線程安全對象的情況。

package com.mzsx.spring.notsingleton;
public interface IUserDao {
 public void add();
 public void delete();
 public void load();
package com.mzsx.spring.notsingleton;
public class UserDaoImp implements IUserDao {
 @Override
 public void add() {
  System.out.println("dao添加用戶。。。。");
 }
 @Override
 public void delete() {
  System.out.println("dao***用戶。。。。");
 }
 @Override
 public void load() {
  System.out.println("dao加載用戶。。。。");
 }
}
package com.mzsx.spring.notsingleton;
public abstract class UserService {
 protected abstract  IUserDao getUserDao();
 

 public void add() {
  getUserDao().add();
 }
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="
http://www.springframework.org/schema/beans
"

       xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
"

       xsi:schemaLocation="
http://www.springframework.org/schema/beans

           
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">

    <bean id="userDao" class="com.mzsx.spring.notsingleton.UserDaoImp" scope="prototype"></bean>

    <bean id="userService" class="com.mzsx.spring.notsingleton.UserService" >

     <lookup-method name="getUserDao" bean="userDao"  /> 

    </bean>
package com.mzsx.spring.notsingleton;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMain {
 private BeanFactory factory= new ClassPathXmlApplicationContext("beans1.xml");
 @Test
 public void notSingleton(){
  UserService users=(UserService)factory.getBean("userService");
  System.out.println(users.getUserDao());
  UserService users1=(UserService)factory.getBean("userService");
  System.out.println(users1.getUserDao());
  
 }
}

結果:

2014-6-3 22:00:10 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons

信息: Pre-instantiating singletons in 
org.springframework.beans.factory.support.DefaultListableBeanFactory@5bb966
: defining beans [userDao,userService]; root of factory hierarchy

com.mzsx.spring.notsingleton.UserDaoImp@caf6c1

com.mzsx.spring.notsingleton.UserDaoImp@10e35d5

需要使用cgLib。

第二種方式:ApplicationContextAware

package com.mzsx.spring.notsingleton2;
public interface IUserDao {
 public void add();
 public void delete();
 public void load();
package com.mzsx.spring.notsingleton2;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class UserDaoImp implements IUserDao,ApplicationContextAware {
 private ApplicationContext app;
 
 @Override
 public void add() {
  System.out.println((IUserDao)app.getBean("userDao"));
  System.out.println("dao添加用戶。。。。");
 }
 @Override
 public void delete() {
  System.out.println("dao***用戶。。。。");
 }
 @Override
 public void load() {
  System.out.println("dao加載用戶。。。。");
 }
 @Override
 public void setApplicationContext(ApplicationContext app)
   throws BeansException {
  // TODO Auto-generated method stub
  this.app=app;
 }
}
package com.mzsx.spring.notsingleton2;
public  class UserService {
 private IUserDao userDao;
 public IUserDao getUserDao() {
  return userDao;
 }
 public void setUserDao(IUserDao userDao) {
  this.userDao = userDao;
 }
 public void add() {
  userDao.add();
 }
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="
http://www.springframework.org/schema/beans
"

       xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
"

       xsi:schemaLocation="
http://www.springframework.org/schema/beans

           
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
">

    <bean id="userDao" class="com.mzsx.spring.notsingleton2.UserDaoImp" scope="prototype"></bean>

    <bean id="userService" class="com.mzsx.spring.notsingleton2.UserService" >

     <property name="userDao" ref="userDao"></property>

    </bean>
package com.mzsx.spring.notsingleton2;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMain {
 private BeanFactory factory= new ClassPathXmlApplicationContext("beans2.xml");
 @Test
 public void notSingleton(){
  UserService users=(UserService)factory.getBean("userService");
  users.add();
  UserService users1=(UserService)factory.getBean("userService");
  users1.add();
  
 }
}


結果:d

2014-6-3 22:03:20 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons

信息: Pre-instantiating singletons in 
org.springframework.beans.factory.support.DefaultListableBeanFactory@1e903d5
: defining beans [userDao,userService]; root of factory hierarchy

com.mzsx.spring.notsingleton2.UserDaoImp@1554d32

dao添加用戶。。。。

com.mzsx.spring.notsingleton2.UserDaoImp@13f136e

dao添加用戶。。。。

 

ApplicationContextAware接口,此接口定義了一個方法setApplicationContext()方法,此方法在Spring初始化類以後,調用實現了ApplicationContextAware接口的類的setApplicationContext()方法,將自身的一個引用傳遞給此實例。

我們將這兩種單例調用非單例的例子對比一下,不難看出,第一種方式:方法注入要好於第二種方式:實現接口。原因是,第二種方式與Spring綁定了。而第一種方式則沒有這種情況,在Service中,我們根本看不出Spring的影子。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章