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.