今天學習spring的bean組件裝載功能,個人不太喜歡xml文件一個個配置bean的方式,所以主要學習測試注解式的自動裝載方式。下面將簡單說明下@Component的用法,簡單入門示例獻給大家。
實現主要步驟說明:
1、ApplicationContext.xml(spring上下文環境配置)文件先配置好需要自動掃描的包位置。注冊完成后,在spring初始化上下文環境時,會自動掃描聲明的包以及子包下面有注解(@Component,@Repository,@Service,@Controller)的類型,並緩存起來。這里需要提一下@Component是一個基礎的注解,不對代碼功能分類進行區分,@Repository一般用於業務邏輯層的類注解,@Service用於dao層注解,@Controller用於控制器注解。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 定義 bean 的 id,以及對應的 java 類 -->
<context:component-scan base-package="com.spring.simm" use-default-filters="true"/>
<!--<bean id="helloWorld" class="com.spring.simm.impls.HelloWorld"> <property name="message" value="Hello World!" /> </bean>-->
</beans>
2、添加一個HelloWorld組件。需要注意的是@Component注解的組件,默認都是單例模式,即缺省的@Scope("singleton")。通過spring去getBean實例時,其實都是同一個對象。我這里將改組件設置成多例模式,即添加注解@Scope("prototype")。
@Scope的模式有:singleton、prototype、request、session、global session,其他模式各位可以查閱網上資料
public interface IHelloWorld { void say(String name); }
@Scope("prototype") //@Scope("singleton")
@Component("hello") public class HelloWorld implements IHelloWorld { private static int no = 0; public HelloWorld(){ no++; System.out.println("IHelloWorld[" + no +"]運行"); } /** * 說話 */
public void say(String name) { // TODO Auto-generated method stub
System.out.println(name +" : hello world!"); } }
3、再添加一個HelloWorldService組件,注解成@Service,單例模式(后面,我們針對單例、多例兩個組件的表現進行測試)。在服務內聲明了一個自動裝載的HelloWorld組件(@AutoWired),通過getHelloWorld方法返回,由於服務類是單例模式,因此這個helloworld對象也是唯一的,在服務的整個生命周期中不變。getHelloWorld2方法則每次都創建一個新的HelloWorld對象。
public interface IHelloWorldService { HelloWorld getHelloWorld(); HelloWorld getHelloWorld2(); }
/** * Hello world 服務,默認情況下就是單例的 * @author wh-simm * */ @Service("helloservice") public class HelloWorldService implements IHelloWorldService { private static int no = 0; public HelloWorldService(){ no++; System.out.println("HelloWorldService["+no+"]啟動"); } /** * 自動裝載 */ @Autowired private HelloWorld helloWorld; /** * 獲取自動裝載的實例 */
public HelloWorld getHelloWorld(){ return helloWorld; } /** * 新建實例 */
public HelloWorld getHelloWorld2(){ return new HelloWorld(); } }
4、添加測試代碼
public class app { public static void main(String[] args) { // 獲取 classpath 中的 Beans.xml 到上下文 context //1.裝載spring上下文配置文件,完成spring容器的初始化
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); //2.從spring容器中獲取bean-helloworld 實例1
IHelloWorld obj1 = (IHelloWorld) context.getBean("hello"); obj1.say("simm1"); //3.從spring容器中獲取bean-helloworld 實例2
IHelloWorld obj2 = (IHelloWorld) context.getBean("hello"); obj2.say("simm2"); //3.從spring容器中獲取bean-HelloWorldService 實例1(單例)
IHelloWorldService service = (IHelloWorldService)context.getBean("helloservice"); service.getHelloWorld().say("simm3"); service.getHelloWorld().say("simm4"); //3.從spring容器中獲取bean-HelloWorldService 實例2(單例)
IHelloWorldService service2 = (IHelloWorldService)context.getBean("helloservice"); service2.getHelloWorld2().say("simm5"); service2.getHelloWorld2().say("simm6"); // 關閉上下文,防止內存泄漏
((ClassPathXmlApplicationContext) context).close(); } }
5、測試結果顯示,從spring容器中兩次獲取HelloWorldService服務,確實只運行了一次,說明默認情況下Component確實是單例的,而HelloWorld組件每次獲取都是創建新的對象,屬於多例模式。服務中自動裝載的HelloWorld組件(@AutoWired)在單例的組件中使用時,要考慮清楚對象的生命周期。
參考資料
https://www.cnblogs.com/lonecloud/p/5745902.html
http://blog.csdn.net/qiuhan/article/details/45581371