Spring能夠在classpath下自動掃描,偵測和實例化具有特定註解的組件,這在Spring中成為組件掃描(Component scanning). @Component:基本註解,標識了一個受spring管理的組件. @Repository:標識持久層組件 @Service:標識服務層(業務層
Spring能夠在classpath下自動掃描,偵測和實例化具有特定註解的組件,這在Spring中成為組件掃描(Component scanning).
特定組件的註解包括:
@Component:基本註解,標識了一個受spring管理的組件.
@Repository:標識持久層組件
@Service:標識服務層(業務層)組件
@Controller:標識表現層組件
對於掃描上的組件,Spring有預設的命名策略,使用非限定類名,第一個字母小寫,也可以在註解中通過value屬性值表示組件的名稱.
當在組件上使用了特定的註解之後,還需要在spring的配置文件中聲明:
<context:component-scan base-package="com.wang" resource-pattern="dao/*.class"></context:component-scan>
其中bese-package是必須的屬性,resource-pattern是可選的屬性
bese-package:制定一個需要掃描的基類包Spring容器將會掃描這個基類包及其子類包中的所有類.當需要掃描多個包時,可以使用逗號隔開.
resource-pattern:如果僅希望掃描特定的類,而非基包下的所有類,可以使用這個屬性過濾特定的類.如上即表示只掃描com.wang的子包dao中的所有類.
組件裝配:
<context:component-scan>元素還會自動註冊AutowiredAnnotationBeanPostProcessor實例,該實例可以自動裝配具有@autowired,@Resource,@Inject註解的屬性.
使用@Autowired自動裝配bean:
@Autowired註解自動裝配具有相容類型的單個Bean屬性:
構造器,普通欄位,一切具有參數的方法上都可以使用@autowired
預設情況下,所有使用@Autowired註解的屬性都需要被設置,當Spring找不到匹配的Bean裝配屬性時,會拋出異常,如果某一屬性允許不被設置,可以設置@Autowired註解的required=false
預設情況下,當IOC容器中存在多個類型相容的bean時,通過類型的自動裝配將無法工作,此時可以在@Qualifier註解里提供Bean的名稱.
@Autowired註解也可以應用在數組類型,集合屬性,Map類型上.
下麵通過一個例子,來應用一下上面的知識點,包結構和類如下,是一個簡單的mvc結構對User實現增刪改查的例子:
User類:
//主要演示註解,這裡不再定義屬性
public class User {
}
UserDao介面:
public interface UserDao {
public void add();
public void delete();
public void update();
public void search();
}
UserDaoImpl類:
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("添加用戶");
}
@Override
public void delete() {
System.out.println("刪除用戶");
}
@Override
public void update() {
System.out.println("更新用戶");
}
@Override
public void search() {
System.out.println("查詢用戶");
}
}
UserService類:
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void add() {
userDao.add();
System.out.println("service add..");
}
public void delete() {
userDao.delete();
System.out.println("service delete..");
}
public void update() {
userDao.update();
System.out.println("service update..");
}
public void search() {
userDao.search();
System.out.println("service search..");
}
}
UserAction類:
@Controller
public class UserAction {
@Autowired
private UserService userService;
@Autowired(required=false)
private User user;
public String add(){
userService.add();
System.out.println("UserAction add..");
System.out.println(user);
return null;
}
public String delete(){
userService.delete();
System.out.println("UserAction delete..");
return null;
}
public String update(){
userService.update();
System.out.println("UserAction update..");
return null;
}
public String search(){
userService.search();
System.out.println("UserAction search..");
return null;
}
}
配置文件beans.xml:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 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.2.xsd">
<context:component-scan base-package="com.wang" />
</beans>
測試代碼:
public class Test1 {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
UserAction userAction=(UserAction) ctx.getBean("userAction");
userAction.add();
}
}
列印結果:
添加用戶
service add..
UserAction add..
null
因為在User類中,我們沒有添加任何註解信息,而在UserAction類中定義屬性user時,又在@Autowired中添加了required="false",所有列印出來的user為null.