概要:
再classpath中掃描組件
- 組件掃描(component scanning):Spring可以從classpath下自己主動掃描。偵測和實例化具有特定注解的組件
- 特定組件包含:
- @Component:基本注解。標示了一個受Spring管理的組件(能夠混用。spring還無法識別詳細是哪一層)
- @Respository:建議標識持久層組件(能夠混用。spring還無法識別詳細是哪一層)
- @Service:建議標識服務層(業務層)組件(能夠混用,spring還無法識別詳細是哪一層)
- @Controller:建議標識表現層組件(能夠混用,spring還無法識別詳細是哪一層)
- 對于掃描到的組件,Spring有默認的命名策略:使用非限定類名,第一個字母小寫(UserServiceImpl-》userServiceImpl),也能夠再注解中通過value屬性值標識組件的名稱(通常能夠將UserServiceImpl —》userService,能夠將Impl拿掉,這是一個習慣)
- 當在組件類中使用了特定的注解之后,還須要在Spring的配置文件里聲明<context:component-scan>:
- base-package屬性指定一個須要掃描的基類包,Spring容器將會掃描整個基類包里及其子包中的全部類
- 當須要掃描多個包時,能夠使用逗號分隔
- 假設僅希望掃描特定的類而非基包下的全部類,可使用resource-pattern屬性過濾特定的類。實例:
?
- <context:include-filter>子節點表示要包括的目標類
- <context:exclude-filter>子節點表示要排除在外的目標類
- <context:component-scan>下能夠擁有若干個<context:include-filter>和<context:exclude-filter>子節點
- <context:include-filter>和<context:exclude-filter>子節點支持多種類型的過濾表達式:
?
- <context:component-sacn>元素還會自己主動注冊AutowireAnnotationBeanPostProcessor實例。該實例能夠自己主動裝配具有@Autowired和@Resource、@Inject注解的屬性
- @Autowired注解自己主動裝配具有兼容類型的單個Bean屬性
- 能夠放在構造器或普通字段(即使是非public)或一切具有參數的方法都能夠應用@Authwired注解
- 默認情況下,全部使用@Autowired注解的屬性都須要被設置。當Spring找不到匹配的Bean裝配屬性時,會拋出異常。若某一屬性同意不被設置,能夠設置@Authwired注解的required屬性為false
- 默認情況下,當IOC容器里存在多個類型兼容的Bean時(@Autowired先是依照類型匹配Bean。假設存在多個類型同樣的Bean,此時IOC容器會去尋找與屬性名同樣名字的Bean),通過類型的自己主動裝配將無法工作,此時能夠在@Qualifier注解里Bean屬性的名稱。Spring同意對方法的方法的輸入參數標注@Qualifier以指定注入Bean的名稱
- @Authwired注解也能夠應用在數組類型的屬性上。此時Spring將會把全部匹配的Bean進行自己主動裝配
- @Authwired注解也能夠應用在集合屬性上。此時Spring讀取該集合的類型信息。然后自己主動裝配全部與之兼容的Bean
- @Authwired注解用在java.util.Map上時,若該Map的鍵值為String,那么Spring將會自己主動裝配與之Map值類型兼容的Bean,此時Bean的名稱作為鍵值
- Spring還支持@Resource和@Inject注解。這兩個注解和@Autowired注解的功能類似
- @Resource注解要求提供一個Bean名稱的屬性,若該屬性為空,則自己主動採用標注處的變量或方法名作為Bean的名稱
- @Inject和@Autowired注解一樣也是依照類型匹配注入的Bean,但沒有required屬性
- 建議使用@Autowired注解
package com.coslay.beans.annotation;import org.springframework.stereotype.Component;public class TestObject {}
package com.coslay.beans.annotation.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;import com.coslay.beans.annotation.service.UserService;@Controller
public class UserController {@Autowiredprivate UserService userService;public void execute(){System.out.println("UserController execute...");userService.add();}
}
package com.coslay.beans.annotation.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;import com.coslay.beans.annotation.reporsitory.UserRepository;@Service
public class UserService {private UserRepository userRepository;//假設有多個類型匹配時。則會去匹配與這個屬性名字同樣的Bean的名字//@Repository("userRepository")//public class UserRepositoryImpl implements UserRepository{//由于名字同樣所以匹配成功//能夠將@Autowired放在字段或者方法上//假設沒有指定名字//另一種方法是使用@Qualifier("userRepositoryImpl")//用來指定哪一個指定名字的Bean//能夠將該標簽放在字段,設置方法或者設置方法的傳入參數前面@Autowired@Qualifier("userRepositoryImpl")public void setUserRepository(UserRepository userRepository){this.userRepository = userRepository;}// @Autowired
// public void setUserRepository(@Qualifier("userRepositoryImpl") UserRepository userRepository){
// this.userRepository = userRepository;
// }public void add(){System.out.println("UserService add...");userRepository.sava();}
}
package com.coslay.beans.annotation.reporsitory;public interface UserRepository {void sava();}
package com.coslay.beans.annotation.reporsitory;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;import com.coslay.beans.annotation.TestObject;@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository{@Autowired(required=false)private TestObject testObject;@Overridepublic void sava() {System.out.println("UserRepository Save...");System.out.println(testObject);}}
package com.coslay.beans.annotation.reporsitory;import org.springframework.stereotype.Repository;@Repository
public class UserJdbcRepository implements UserRepository {@Overridepublic void sava() {System.out.println("UserJdbcRepository sava...");}}
package com.coslay.beans.annotation;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.coslay.beans.annotation.controller.UserController;
import com.coslay.beans.annotation.reporsitory.UserRepository;
import com.coslay.beans.annotation.service.UserService;public class Main {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");// TestObject to = (TestObject) ctx.getBean("testObject");
// System.out.println(to);
// UserController userController = (UserController) ctx.getBean("userController");System.out.println(userController);userController.execute();//
// UserService userService = (UserService) ctx.getBean("userService");
// System.out.println(userService);
//
// UserRepository userRepository = (UserRepository) ctx.getBean("userRepository");
// System.out.println(userRepository);}
}
<?
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-4.0.xsd"> <!-- 指定Spring IOC 容器掃描的包 --> <!-- 能夠通過resource-pattern指定掃描的資源 --> <!-- <context:component-scan base-package="com.coslay.beans.annotation" resource-pattern="reporsitory/*.class"> </context:component-scan> --> <!-- context:exclude-filter 子節點指定排除哪些指定表達式的組件 context:include-filter 子節點指定包括哪些表達式的組件,該子節點須要use-default-filters="false"配合使用(假設use-default-filters="ture"則使用系統默認掃描全部帶有@Component@Controller@Service@Repository的組件) --> <context:component-scan base-package="com.coslay.beans.annotation"> <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> --> <!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> --> <!-- <context:exclude-filter type="assignable" expression="com.coslay.beans.annotation.reporsitory.UserRepository"/> --> <!-- <context:include-filter type="assignable" expression="com.coslay.beans.annotation.reporsitory.UserRepository"/> --> </context:component-scan> </beans>