天天看点

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;