使用註解配置
步驟
- 導包(4+2+1)
基本4個元件包加2個日誌包(log4j,logging),再加aop
- 將物件註冊到容器中
spring 中提供@Component 的三個衍生註解:(功能目前來講是一致的)
如果不指定任何屬性時,預設使用短類名作為bean的id(首字母改成小寫)
@Component("user")
@Service("user") //業務層service層物件
@Controller("user") //Web層物件
@Repository("user") //持久層dao層物件
複製程式碼
這三個註解是為了讓標註類本身的用途清析
- 指定物件的作用範圍(==單例還是多例==)
@Scope("prototype")
複製程式碼
- 依賴注入(使用註解注入的方式, 可以不用提供 set 方法)
@Value :用於注入普通型別. @Autowired :自動裝配:
- 預設按型別進行裝配.
- 按名稱注入:
- @Qualifier:強制使用名稱注入. @Resource 相當於:
- @Autowired 和@Qualifier 一起使用.
@AutoWired預設按型別裝配(而且這個註解是屬於Spring的).預設情況下依賴的物件必須存在.如果要允許null值,可以設定它的required屬性為false @Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier註解進行使用
@Autowired()
@Qualifier("baseDao")
private BaseDao baseDao;
複製程式碼
@Resource預設按照名稱進行裝配.該名稱可以通過註解中name屬性進行指定.如果沒有指定name屬性,當註解寫在欄位上時,預設取欄位名,按照名稱查詢,如果註解寫在setter方法上預設取屬性名進行裝配。當找不到與名稱匹配的bean時才按照型別進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。
如果介面有多個實現類,我們需要指定要注入的哪個實現類
@Resource(name = "manImpl")//注意是manImpl不是ManImpl,因為使用@Service,容器為我們建立bean時預設類名首字母小寫
private Human human;
@Autowired
@Qualifier("manImpl")
private Human human;
複製程式碼
Spring屬於第三方的,J2EE是Java自己的東西。使用@Resource可以減少程式碼和Spring之間的耦合.
- 值型別注入
通過反射的field賦值,破壞了封裝性.不推薦使用
@Value("tom")
private String name;
@Value("18")
private Integer age;
複製程式碼
通過set方法賦值(推薦使用)
@Value("tom")
public void setName(String name) {
this.name = name;
}
複製程式碼
- 引用型別注入
使用@Autowired(自動裝配),會幫我們自動查詢該型別的物件,並賦值.@Qulifier通常與Autowired一起使用.可以指定容器中的哪一個物件,賦值給引用型別的屬性
@Component("user")
public class User {
private String name;
@Value("18")
private Integer age;
//@Resource(name="car")
@Autowired
@Qualifier("car2")
private Car car;
複製程式碼
@AutoWired:
作用:如果spring容器中同一個型別有多個bean存在,則需要根據變數名稱和bean的id進行比較。如果有相同則能注入成功;否則注入失敗。
@Autowired 在方法上的時候.當專案啟動,載入web.xml時.springIOC容器建立 會掃描指定的包下的所有註解.當掃描的時候會例項所有被載入的類,類中方法上有@autowired的註解時,會呼叫這個方法.
@Repository
public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao {
//@Autowired
//private HibernateTemplate hibernateTemplate;
//@Autowired // 私有成員變數的注入
//private SessionFactory sessionFactory;
/*
* 1. tomcat啟動,載入自身web.xml
* 2. 載入所有專案的web.xml
* 3. 建立Spring的IOC容器
* 4. 掃描所有的cn.itcast包, 掃描@Repository、@Autowired
* 5. 當前掃描到@Autowired時候,會根據方法引數的型別,去容器找該型別對應的物件,注入到方法引數中。
*/
@Autowired
public void setSf(SessionFactory sessionFactory){
// 呼叫父類的方法
super.setSessionFactory(sessionFactory);
}
@Override
public List<Person> findAll() {
return getHibernateTemplate().loadAll(Person.class);
}
}
複製程式碼
@Qualifier:
作用:在注入資料時,可以配合@Autowired註解一起使用。在按照型別注入的基礎上,按照bean的id注入.
注意:
- 在給類的成員變數注入資料時,不能單獨使用,需要配合@Autowired註解一起使用
- 在給方法的形參注入資料時候,可以單獨使用
@Resource.需要我們手動注入.指定注入容器中的哪一個物件.(推薦使用)
預設情況下(不指定屬性),它會先根據變數名稱注入,注入不成功;再根據型別注入.
@Component("user")
public class User {
private String name;
@Value("18")
private Integer age;
@Resource(name="car")
private Car car;
複製程式碼
- 初始化與銷燬方法
@PostConstruct 初始化
@PreDestroy 銷燬
@PostConstruct
public void init() {
System.out.println("物件被初始化!");
}
@PreDestroy
public void destory() {
System.out.println("物件被銷燬了!");
}
複製程式碼
注意:scope為prototype的bean,容器會將建立好的物件例項返回給請求方,之後,容器就不再擁有其引用,請求方需要自己負責當前物件後繼生命週期的管理工作,包括該物件的銷燬。
所以:scope為singleton的bean的destroy方法則是在容器關閉時執行,而scope為prototype的bean是不會執行destroy方法的。
- 配置檔案applicationContext.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd ">
<context:component-scan base-package="supreme.pojo"></context:component-scan>
</beans>
複製程式碼
<context:component-scan base-package="supreme.pojo"></context:component-scan>掃包,掃描包下的所有類,包括子類,子類的子類.
AnnotationConfigApplicationContext:
它是註解使用的容器實現類,作用相當於ClassPathXmlApplicationContext。
@Configuration
作用:把當前類標識為配置類,作用與bean.xml檔案相同
@ComponentScans
作用:建立spring容器的時候要掃描的包
@Import
作用:引入其它的配置類
@PropertySource
作用:匯入其他屬性檔案
@Bean:
作用:指定把方法的返回值,放入spring容器中
@Qualifier:
作用:在方法形參上使用,可以獨立使用,指定根據bean的id進行注入
方法引數取值注意事項:
-
如果按照引數型別,在spring容器中只有一個物件,則spring可以自動按照型別注入
-
如果按照引數型別,在spring容器中有多個物件,則需要使用@Qualifier註解明確告訴spring,使用哪一個物件