Spring --07.Spring框架中bean管理的常用註解
Spring中用於管理bean的註解分為四大類:
1)、用於建立物件
2)、用於給物件中的屬性注入值
3)、用於改變作用範圍
4)、用於定義生命週期
1、用於建立物件
用於建立物件的有四個:@Component,@Controller,@Service,@Repository
(1)、@Component註解
作用:把資源讓Spring來管理、相當於在Xml中配置一個bean
屬性:value:指定bean的id值、如果不指定value屬性、預設bean的id是當前 類的類名、首字母小寫
(2)、@Controller,@Service,@Repository
他們三個註解都是針對一個的衍生註解,他們的作用及屬性都是一模一樣的。
他們只不過是提供了更加明確的語義化。
@Controller:一般用於表現層的註解。
@Service:一般用於業務層的註解。
@Repository:一般用於持久層的註解。
@Service的用法:修改UserServiceImpl類,把@Component改成@Service
//@Component("userService") @Service("userService")//@Service加在業務層的bean,value屬性指定bean的id public class UserServiceImpl implements UserService{ @Override public void saveUser() { System.out.println("業務層:使用者儲存..."); } }
@Repository的用法:建立UserDao介面:
建立UserDao.java介面和UserDaoImpl.java實現類
package com.day01.dao;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 14:00 2018/11/8
*/
public interface UserDao {
public abstract void save();
}
package com.day01.dao.Impl; import com.day01.dao.UserDao; import org.springframework.stereotype.Repository; /** * @ Author :ShaoWei Sun. * @ Date :Created in 14:01 2018/11/8 */ @Repository("userDao")//@Repository加在dao層的bean,value屬性指定bean的id public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("持久層。。。。"); } }
applicationContext.xml、要把掃描的包定義為com.day01,不然的其它包的註解就不能識別了
<?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.xsd">
<context:component-scan base-package="com.day01"/>
</beans>
測試
package com.day01.test;
import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 13:35 2018/11/8
*/
public class TestIOC {
@Test
public void test2(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.save();
}
}
@Controller:
@Controller("userAction")//@Controller加在web層的bean,value屬性指定bean的id
public class UserAction {
}
2、用於給物件屬性注入值
用於給物件屬性注入資料的註解有:
@Value、@Autowired、@Qualifier、@Resource
相當於:<property name="" ref=""> /<property name="" value="">
<bean id="people" class="com.day01.domain.People">
<property name="name" value="小剛"></property>
<property name="address" value="上海"></property>
<property name="car" ref="car"></property>
</bean>
(1)、@Value
作用:注入基本資料型別和String型別資料
屬性:value:用於指定值
修改UserDaoImpl.java、增加一個字串屬性name、通過@Value註解實現
package com.day01.dao.Impl;
import com.day01.dao.UserDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 14:01 2018/11/8
*/
@Repository("userDao")//@Repository加在dao層的bean,value屬性指定bean的id
public class UserDaoImpl implements UserDao {
@Value("小羅")//@Value給基本型別和字串型別注入值,value屬性指定要注入的值
private String name;
@Override
public void save() {
System.out.println("持久層。。。。"+name);
}
}
測試
@Test
public void test2(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
userDao.save();
}
(2)、@Autowired
作用:
自動按照型別注入。
當使用註解注入屬性時,set方法可以省略。它只能注入其他bean型別。當有多個型別匹配時,
使用要注入的物件變數名稱作為bean的id,在spring容器查詢,找到了也可以注入成功。找不到就報錯。
修改UserServiceImpl類、增加一個物件屬性userDao、現通過@Autowired給userDao注入值
package com.day01.service.Impl;
import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 12:22 2018/11/8
*/
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
@Value("小羅")//@Value給基本型別和字串型別注入值,value屬性指定要注入的值
private String name;
@Autowired //注入物件型別、招照型別注入
private UserDao userDao;
@Override
public void saveUser() {
System.out.println("業務層:儲存使用者。。。。。。"+name);
userDao.save();
}
}
UserDaoImpl.java
package com.day01.dao.Impl;
import com.day01.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 14:01 2018/11/8
*/
@Repository("userDao")//@Repository加在dao層的bean,value屬性指定bean的id
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("持久層。。。。");
}
}
測試類TestIOC.java
package com.day01.test;
import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 13:35 2018/11/8
*/
public class TestIOC {
/**
* 測試註解
*/
@Test
public void test1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.saveUser();
}
}
(3)、@Qualifier
作用:
在自動按照型別注入的基礎之上,再按照Bean的id注入。
它在給欄位注入時不能獨立使用,必須和@Autowire一起使用;但是給方法引數注入時,可以獨立使用。
屬性:value:指定bean的id。
建立UserDao介面的第二個實現類UserDaoImpl2.java
package com.day01.dao.Impl;
import com.day01.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 14:36 2018/11/8
*/
@Repository("userDao2")
public class UserDaoImpl2 implements UserDao {
@Override
public void save() {
System.out.println("持久層:2222.。。。。。。。");
}
}
測試
@Test
public void test1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.saveUser();
}
測試發現、UserServiceImpl中注入的還是第一個UserDaoImpl,因為當有多個bean都滿足的情況下,
優先注入bean的id與屬性的名字一樣的bean;想指定注入UserDaoImpl2,需要使用@Qualifier註解根據名字來注入
UserServiceImpl.java
package com.day01.service.Impl;
import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 12:22 2018/11/8
*/
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
@Value("小羅")//@Value給基本型別和字串型別注入值,value屬性指定要注入的值
private String name;
@Autowired //注入物件型別、招照型別注入
@Qualifier("userDao2")
private UserDao userDao;
@Override
public void saveUser() {
System.out.println("業務層:儲存使用者。。。。。。"+name);
userDao.save();
}
}
測試TestIOC.java
package com.day01.test;
import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 13:35 2018/11/8
*/
public class TestIOC {
/**
* 測試註解
*/
@Test
public void test1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.saveUser();
}
}
修改UserServiceImpl.java再次測試、就會發現UserServiceImpl中注入的是UserDaoImpl2
(4)、@Resource
作用:直接按照Bean的id注入。它也只能注入其他bean型別。
屬性:name:指定bean的id。
修改UserServiceImpl類,使用@Resource給userDao注入值。@Resource是按照bean的id來注入,只能注入物件型別
《@Resource註解不起作用》
3、用於改變作用域範圍
@Scope
作用:指定bean的作用範圍
屬性:value:指定範圍的值。取值:singleton prototype request session globalsession
修改UserServiceImpl,在該類上加@Scope註解,指定該類是多例的的,預設是單例的。給該類顯示指定一個無參構造方法,方便測試
package com.day01.service.Impl;
import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 12:22 2018/11/8
*/
//@Component("userService")
@Service("userService")
@Scope("prototype")
public class UserServiceImpl implements UserService {
public UserServiceImpl() {
System.out.println("呼叫了無參構造。。。。。");
}
@Value("小羅")//@Value給基本型別和字串型別注入值,value屬性指定要注入的值
private String name;
@Autowired //注入物件型別、招照型別注入
@Qualifier("userDao2")
//@Autowired()
private UserDao userDao;
@Override
public void saveUser() {
System.out.println("業務層:儲存使用者。。。。。。"+name);
userDao.save();
}
}
測試TestIOC.java
@Test
public void test3(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ac.getBean("userService");
UserService userService1 = (UserService) ac.getBean("userService");
System.out.println(userService1+ " = " +userService);
}
4、用於定義生命週期
相當於applicationContent.xml中的
<bean id="" class="" init-method="" destroy-method="" />
@PostConstruct註解 @PreDestory註解
(1)、@PostConstruct
說明:@PostConstruct加在方法上,指定bean物件建立好之後,呼叫該方法初始化物件,類似於xml的init-method方法。修改UserServiceImpl類,在其中增加一個init方法,在該方法上指定@PostConstruct註解
《不呼叫這@PostConstruct這個方法》
(2)、@PreDestory
@PreDestory加在方法上,指定bean銷燬之前,呼叫該方法,類似於xml的destory-method方法。修改UserServiceImpl類,在該類中增加一個destroy方法,在該方法上加@PreDestroy註解
《不呼叫這@PreDestory這個方法》
註解總結:
與建立Bean物件相關:
@component @Controller @Service @Repository
與屬性注入值相關:
@Value @Autowired @Qulifier @Resource
與範圍相關
@Scope
與生命週期相關
@PostConstruct @PreDestroy
5、XML和註解的比較
註解的優勢:配置簡單,維護方便。(我們找到了類,就相當於找到了配置)
XML的優勢:修改時,不用改原始碼。不涉及重新編譯和部署。