程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Spring進階之路(12)-注解方式實現Bean的注入

Spring進階之路(12)-注解方式實現Bean的注入

編輯:JAVA綜合教程

Spring進階之路(12)-注解方式實現Bean的注入


鑒於之前的博文中都是通過在xml中對bean進行配置的方式注入的,又加上博友的要求,決定對注解方式進行一個簡單的講解,這裡不會涉及太復雜的程序,因為本文的目的是讓看到這篇博文的廣大博友能懂,而不是雲裡霧裡的怎麼也看不明白。

常用的注解

1. @Controller:標注一個控制器組件的類。

2. @Service:標注一個業務邏輯組件的類。

3. @Repository:標注一個Dao組件的類。

4. @Component:標注一個普通的類。

這幾個注解主要用於標注Spring要進行實例化的類,一旦在某個類的上面標注了這樣的注解,如果是單例模式的話,那麼Spring在初始化的時候,就會將這些類實例化,而對於非單例模式的類,不取決於Spring容器本身,往往是客戶端進行請求的時候,進行創建實例(Spring創建的),這些在之前的博文中已經進行過說明,請參考Spring進階之路(7)-Bean的生命周期以及創建、銷毀執行流程。

5. @Resource:按照名稱(name)進行注入。該注解屬於jdk中的注解,但是在項目中使用比較廣泛。

6. @Autowired:按照類型匹配自動注入。

這裡的兩個注解主要用於為類中屬性注入值。兩個注解可以將(上面四個注解標注的類在Spring中實例化後的對象)注入到某些類的屬性中。

7. @Scope("prototype"):默認的情況下是產生單例對象,在Scope的裡面傳了prototype的參數後,表明該類不是單例的,而是"多例的",不知道這麼解釋標准不標准,讀者可以糾正。

8. @PostConstruct:指定bean的初始化方法與之前博文中配置文件指定的initMethod作用相同(Spring進階之路(7)-Bean的生命周期以及創建、銷毀執行流程),Spring會在Bean的依賴注入完成後回調這個方法。

9. @PreDestroy:指定bean的銷毀之前的方法與Spring進階之路(7)-Bean的生命周期以及創建、銷毀執行流程這篇博文中配置文件指定的destroyMethod的作用是一樣的,他會在bean銷毀之前調用。

 

另外:

10: @Lazy:用於指定該類是否取消預初始化。指定參數boolean型true即可,下面不在贅述,這個注解比較簡單。

11: @DependsOn:可以修飾類或者方法,用於強制初始化一些bean,例?a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="4fa8ecf50f0b2a3f2a212b3c0021">[email protected]({"wy", "wangyang"}),這樣在初始化之前會強制初始化裡面的bean.

實例演示

用注解進行自動注入bean的前提是在配置文件中配置了自動注入的支持。

 



		
	

下面來展示一個簡化版的用戶登錄功能

 

控制器組件:

用到了@Controller、@Scope、@Resource、@Autowired四個注解,如果這裡沒有被注入進來的話,會在調用的地方拋出空指針異常,如果不拋出空指針就說明bean已經被注入進來了。

package com.siti.spring20160316;

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

@Controller
@Scope("prototype")
public class UserAction {

	@Resource
	private UserService userService;
	@Autowired
	private Utils utils;
	
	public boolean login(String userName, String password){
		System.out.println("UserAction--login");
		
		if(utils.check(userName)){
			if(userService.login(userName, password)){
				return true;
			}
		}
		return false;
	}
	
}

Service業務邏輯層

在這裡說明下,一般我們開發中比較喜歡用接口,這裡是為了看起來清楚沒有采用接口的形式,避免讀者看的雲裡霧裡搞不清楚流程。

這裡主要用到的注解有@Service(標注業務邏輯層)、@PostCustruct(標注的方法相當於initMethod)、@PreDestroy(標注的方法相當於destroyMethod)

package com.siti.spring20160316;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.stereotype.Service;
/**
 * 
 * @ProjectName SpringBlob
 * @ClassName UserService
 * @Description 一般情況下,都是采用接口的,這裡沒有使用接口,便於讀者直接看清楚調用關系
 * @author wy
 * @date 2016-3-16
 *
 */
@Service
public class UserService {

	@Resource
	private UserDao userDao;
	
	public boolean login(String userName, String password){
		System.out.println("UserService--login");
		if(userDao.isExist(userName, password)){
			return true;
		}
		return false;
	}
	
	@PostConstruct
	public void init(){
		System.out.println("UserService--init");
	}
	
	@PreDestroy
	public void destroyMethod(){
		System.out.println("UserService--destroyMethod");
	}
}
DAO層

主要用到的注解有@Repository

由於這裡屬於模擬沒有加入連接數據庫部分的持久化操作,請見諒。

package com.siti.spring20160316;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {

	public boolean isExist(String userName, String password){
		System.out.println("UserDao--isExist");
		if("wy".equals(userName)){
			return true;
		}
		return false;
	}
}

進行測試

第一個輸出比較兩個得到的對象是不是同一個對象。讀者可以自己檢驗其他的幾個對象是不是同一個。因為UserAction類標注了@Scope的注解並指定其類型為prototype,那麼這裡應該是不一樣的,輸出false

package com.siti.spring20160316;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

	public static void main(String[] args) {
		AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160316.xml");
		UserAction action = (UserAction) context.getBean("userAction");
		UserAction action2 = (UserAction) context.getBean("userAction");
		
		System.out.println("這兩個對象是否是同一個對象:" + action.equals(action2));
		
		boolean bool = action.login("wy", "******");
		if(bool){
			System.out.println("登錄成功!");
		}else{
			System.out.println("登錄不成功!");
		}
		context.registerShutdownHook();
	}
}

輸出結果

\

自定義注解

這裡只是自己寫了個注解,但是沒有解析類是沒辦法去用的,讀者可以試試看能不能自己寫出他的處理類,可以共同交流下。

package com.siti.spring20160316;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)// 運行期間注入
@Target({ElementType.FIELD, ElementType.METHOD})// 可以標注在哪裡,這裡是屬性和方法上
public @interface MyAutowired {
	// 參數
	public String name() default "";
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved