天天看點

Spring核心之6 SpringIOC容器基于注解的元件掃描

1.什麼是元件掃描

指定一個包路徑,Spring會自動掃描該包及其子包所有元件類,當發現元件類定義前有特定的注解标記時,就将該元件納入到spring容器,等價于原有的xml配置中的bean定義功能;

元件掃描可以替代xml配種的bean定義      

2.指定掃描類路徑

使用元件掃描,首先需要在xml配置中指定掃描類路徑      
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"      
<context:component-scan base-package="com.gaoxinfu.demo.spring"></context:component-scan>      

3.自動掃描的注解标記

指定掃描類路徑後,并不是該路徑下所有的元件類都掃描到Spring容器的,隻有在元件類定義前面有以下注解标記時,才會掃描到Spring容器;      

3.1 @Component 通用注解

3.2 @Name 通用注解

3.3 @Repository 持久化層元件注解

3.4 @Service 業務層元件注解

3.5 @Controller 控制層元件注解

4.自動掃描元件的命名

當一個元件在掃描過程中被檢測到時,會生成一個預設id值,預設id為小寫開頭的類名,也可以在注解标記中自定義id,下面兩個元件id名字分别是oracleUserDao和loginService      

5.指定掃描的作用域

通常受Spring管理的元件,預設的作用域是singleton,如果需要其他的作用域可以适用@Scope注解,隻要在注解中國提供作用域的名稱即可;
@Scope("prototype")
@Scope("singleton")      

6.初始化和銷毀回調的控制

@PostConstruct
  public void init() {
    logger.info("ExampleBean2方法init()初始化ExampleBean2對象");
  }      
@PreDestroy
  public void destroy() {
    logger.info("ExampleBean2方法destroy()銷毀ExampleBean2對象");
  }      

7.指定依賴注入關系

具有依賴關系的Bean對象,利用下面的任意一種注解都可以實作關系注入
@Resource
@Autowired/@Qualified
@Inject/@Named      

7.1 @Resource

@Resource注解标記可以用在字段定義或setter方法定義前面,預設首先按名稱比對注入,然後類型比對注入;  
當遇到多個比對Bean時注入會發生錯誤,可以顯示指定名稱例如 @Resource(name="empDao1")      
package com.gaoxinfu.demo.spring.example.service;

import javax.annotation.Resource;

import com.gaoxinfu.demo.spring.example.bean.User;
import com.gaoxinfu.demo.spring.example.dao.UserDAO;

/**
 * 
 * @Description:TODO
 * @Author:gaoxinfu
 * @Time:2018年2月17日 下午5:56:10
 */
public class UserService {

//  @Resource
  private UserDAO userDAO;
  
  public UserDAO getUserDAO() {
    return userDAO;
  }
  @Resource
  public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
  }

  /**
   * 
   * @Title: login   
   * @Description: 使用者登入功能
   * @param name
   * @param pwd
   * @return      
   * @return: User      
   * @throws   
   * @Exception:
   * @Author: gaoxinfu
   * @Time:2018年2月12日 下午4:50:22
   */
  public User login(String name,String pwd) {
    User user=userDAO.findByName(name);
    if (user!=null&&pwd.equals(user.getPwd())) {
      return user;
    }
    return null;
  }
}      

7.2 @Autowired

@Autowired注解标記也可以用在字段或setter方法定義前面,預設按類型呢比對注入
當@Autowired遇到多個比對Bean時注入會發生錯誤,可以使用下面方法指定名稱@Qualified("mysqlUserDao")        
package com.gaoxinfu.demo.spring.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.gaoxinfu.demo.spring.example.bean.User;
import com.gaoxinfu.demo.spring.example.dao.UserDAO;

/**
 * 
 * @Description:TODO
 * @Author:gaoxinfu
 * @Time:2018年2月17日 下午5:56:10
 */
public class UserService {

//  @Autowired
//  @Qualifier("mysqlUserDao")
  private UserDAO userDAO;
  
  public UserDAO getUserDAO() {
    return userDAO;
  }
  @Autowired
  public void setUserDAO(@Qualifier("mysqlUserDao")UserDAO userDAO) {
    this.userDAO = userDAO;
  }

  /**
   * 
   * @Title: login   
   * @Description: 使用者登入功能
   * @param name
   * @param pwd
   * @return      
   * @return: User      
   * @throws   
   * @Exception:
   * @Author: gaoxinfu
   * @Time:2018年2月12日 下午4:50:22
   */
  public User login(String name,String pwd) {
    User user=userDAO.findByName(name);
    if (user!=null&&pwd.equals(user.getPwd())) {
      return user;
    }
    return null;
  }
}      

7.3 @Inject

需要引入javax.inject包

<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>      
@Inject注解标記時Spring3.0開始增加的對JSR-3.0标準的支援,使用前需要添加JSR-3.0的jar包,使用方法與Autowired相似,具體如下      
package com.gaoxinfu.demo.spring.example.service;

import javax.inject.Inject;

import com.gaoxinfu.demo.spring.example.bean.User;
import com.gaoxinfu.demo.spring.example.dao.UserDAO;

/**
 * 
 * @Description:TODO
 * @Author:gaoxinfu
 * @Time:2018年2月17日 下午5:56:10
 */
public class UserService {


  @Inject
  private UserDAO userDAO;
  
  public UserDAO getUserDAO() {
    return userDAO;
  }
  public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
  }

  /**
   * 
   * @Title: login   
   * @Description: 使用者登入功能
   * @param name
   * @param pwd
   * @return      
   * @return: User      
   * @throws   
   * @Exception:
   * @Author: gaoxinfu
   * @Time:2018年2月12日 下午4:50:22
   */
  public User login(String name,String pwd) {
    User user=userDAO.findByName(name);
    if (user!=null&&pwd.equals(user.getPwd())) {
      return user;
    }
    return null;
  }
}      
當@Inject遇到多個比對Bean時注入會發生錯誤,可以使用@Named指定名稱限定,使用方法如下:      
package com.gaoxinfu.demo.spring.example.service;

import javax.inject.Inject;
import javax.inject.Named;

import com.gaoxinfu.demo.spring.example.bean.User;
import com.gaoxinfu.demo.spring.example.dao.UserDAO;

/**
 * 
 * @Description:TODO
 * @Author:gaoxinfu
 * @Time:2018年2月17日 下午5:56:10
 */
public class UserService {


  @Inject
  private UserDAO userDAO;
  
  public UserDAO getUserDAO() {
    return userDAO;
  }
  public void setUserDAO(@Named("mysqlUserDao")UserDAO userDAO) {
    this.userDAO = userDAO;
  }

  /**
   * 
   * @Title: login   
   * @Description: 使用者登入功能
   * @param name
   * @param pwd
   * @return      
   * @return: User      
   * @throws   
   * @Exception:
   * @Author: gaoxinfu
   * @Time:2018年2月12日 下午4:50:22
   */
  public User login(String name,String pwd) {
    User user=userDAO.findByName(name);
    if (user!=null&&pwd.equals(user.getPwd())) {
      return user;
    }
    return null;
  }
}      

8.注入Spring表達式

<util:properties id="jdbcProperties" location="classpath:db.properties" />      
drive=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
name=system
password=system      
然後在setter方法前使用@Value注解      
@Value("#{jdbcProperties.driver}")
  private String driver;