Spring IoC註解詳解

這篇文章記錄Spring IoC通過註解注入屬性的方法。

一、註解注入屬性一個簡單的案例

1)Spring配置文件引入context約束

<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">

</beans>

2)Spring配置文件中開啓註解掃描

<context:component-scan base-package="com.pc.service"/>

注意,在第一步必須要引入context約束,否則無法出現context標籤。

3)在類上添加@Component註解

@Component("user")
public class User {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

4)編寫測試

ApplicationContext act = new ClassPathXmlApplicationContext("beans-ioc.xml");
User user = (User) act.getBean("user");
System.out.println(user);


二、Spring IoC常用註解詳解

1)Bean標註註解

  • @Component :組件通用註解,常用於Model類
  • @Controller :常用於對Controller實現類進行標註
  • @Service:常用於對Service實現類進行標註
  • @Repository:常用於對DAO實現類進行標註

@Component是Spring提供的通用的組件註解。@Component、@Controller、@Service和@Repository功能一樣,可以互換,我們使用不同註解主要爲了區分被註解的類處在不同的業務層,使邏輯更加清晰。這四個註解主要是定義bean,創建bean。

它們使用方法:

(1)標註在類上

(2)@Component("name")等於@Component(value="user")

(3)@Component相當於@Component("className")

2)Bean屬性注入註解

  • @Value :注入普通類型屬性
  • @Resource :注入對象類型
  • @Autowired :注入對象類型,默認按照類型注入。結合@Qualifier註解完成按名稱的注入。

(1)@Value註解

例如,爲上面案例中User類中id和name一個初始值,我們可以在id和name屬性上面使用@Value註解,也可以在它們的set方法上使用@Value註解

@Component(value="user")
public class User {
	@Value("1")
	private Integer id;
	
	@Value("lzgsea")
	private String name;
	public Integer getId() {
		return id;
	}
	
	//@Value("1")
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	
	//@Value("lzgsea")
	public void setName(String name) {
		this.name = name;
	}
}

(2)@Resource :注入對象類型

public class UserTest {
	
	@Resource(name = "user")
	private User user;
	
}

(3)@Autowired註解

public class UserTest {
	
	// 按名注入,需要組件設置名稱
    // @Resource(name = "user")
    // 和上面功能一樣,按名注入
    @Qualifier("user")
    @Autowired
	private User user;
	
}

3)Bean的作用範圍註解@Scope

Bean的範圍的註解:默認是單例的。

@Scope :在類上添加的,控制類生成的時候採用單例還是多例。 

@Scope取值:

  • singleton :單例
  • prototype :多例
  • request :request域,需要在web環境
  • session :session域,需要在web環境
  • application: context域,需要在web環境
  • globalsession 集羣環境的session域,需要在web環境

4)Bean的生命週期註解

@PostConstruct :相當於init-method

@PreDestroy :相當於destroy-method

這兩註解用在方法上面。

    @PostConstruct
    public void init() {
    	System.out.println("初始化方法......");
    }
    
    @PreDestroy
    public void destroy() {
    	System.out.println("銷燬方法......");
    }


三、context:componet-scan

配置<context:annotation-config>後,會掃描@Required、@Autowired、@PostConstruct、@PreDestroy、@Resource等註解。

配置<context:component-scan base-package="xx">標籤後,spring可以自動去掃描base-pack下面或者子包下面的java文件,除了掃描<context:annotation-config>中所有的註解,還會掃描@Component、@Repository、@Service、@Controller、 @RestController、@ControllerAdvice、@Configuration 這些註解。

<context:component-scan>提供了兩個子標籤

  • <context:include-filter>
  • <context:exclude-filter>

在說明這兩個子標籤前,先說一下<context:component-scan>有一個use-default-filters屬性,該屬性默認爲true,這就意味着會掃描指定包下的全部的標有Spring註解的類,並註冊成bean。也就是@Component,@Controller,@Service,@Reposity等。所以如果僅僅是在配置文件中這麼寫

<context:component-scan base-package="lzgsea.*"/>

 use-default-filter此時爲true那麼會對base-package包或者子包下的所有的進行java類進行掃描,並把匹配的java類註冊成bean。

 可以發現這種掃描的粒度有點太大,如果你只想掃描指定包下面的Controller,該怎麼辦?此時子標籤<context:incluce-filter>就起到了勇武之地。如下所示

<context:component-scan base-package="lzgsea.*" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

這樣就會只掃描base-package包或者子包下所有@Controller下的java類,並註冊成bean。

use-dafault-filter在上面並沒有指定,默認就爲true,或者直接use-dafault-filter改爲true,那麼會對base-package包或者子包下的所有的進行java類進行掃描。

<context:component-scan base-package="lzgsea.*">  
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
</context:component-scan>  

此時,spring不僅掃描了@Controller,還掃描了指定包所在的子包service包下註解@Service的java類。此時指定的include-filter不任何起到作用。

另外在我參與的項目中可以發現在base-package指定的包中有的子包是不含有註解了,所以不用掃描,此時可以指定<context:exclude-filter>來進行過濾,說明此包不需要被掃描。

綜合以上說明:

use-default-filters="false"的情況下不會自動掃描,需要配置<context:include-filter>指定掃描哪些註解

use-dafault-filters="false"的情況下:<context:include-filter>指定的掃描。

use-default-filters="true"的情況下:<context:exclude-filter>指定的不掃描

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