1. 程式人生 > >Spring --07.Spring框架中bean管理的常用註解

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的優勢:修改時,不用改原始碼。不涉及重新編譯和部署。