第一種方式:方法注入
方法注入在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的影子。