1.准备工作

(1)导入jar包

除了上篇文章使用到的基本jar包外,还得加入aop的jar包,所有jar包如下

所需jar包

(2)配置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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描,到包里面扫描类、属性、方法上是否有注解 -->
<context:component-scan base-package="com.codeliu"/>
</beans>

2.注解实例化Bean

(1)实例化Bean有四个注解

  • @Component
  • @Service:业务层
  • @Controller:WEB层
  • @Repository:持久层

虽然分了层,但目前这四个注解的功能是一样的。

@Service(value = "user") //相当于bean标签中的id,四种方式功能一样
// @Component(value = "user")
// @Controller(value = "user")
// @Repository(value = "user")
@Scope(value = "singleton")
public class User {
public void print() {
System.out.println("user......");
}
}
    @Test
/**
* 使用注解实例化User类
*/
public void testUser() {
// 读取配置文件
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = (User)context.getBean("user");
user.print();
}

bean的作用域配置

  Spring中可以使用scope属性来配置bean的作用域:

  singleton:单例,在初始化配置文件时生成单例bean对象

  prototype:原型的,在初始化配置文件时不生成bean对象,使用时返回不同的bean对象

  request:web环境下每一个request请求都会返回一个不同的bean,只在本次请求中有效

  session:web环境下每一个request请求都会返回一个不同的bean,在session中有效

3.注解为属性赋值

首先来个UserDao

@Component(value = "userDao")
public class UserDao {
public void print() {
System.out.println("userdao......");
}
}

再来个service

@Service(value = "userService")
public class UserService {
// 注入对象类型的属性,不用提供set方法
// 1.使用自动装配
// @Autowired // 为byType类型,如果有多个相同类型的,得配合@Qualifier注解
// private UserDao userDao; // 2.不使用自动装配
@Resource(name = "userDao")
private UserDao userDao; // 注入普通类型的属性
@Value(value = "CodeTiger")
private String name; public void print() {
System.out.println("UserService......");
userDao.print();
System.out.println(name);
}
}

为属性赋值,我们可以使用自动装配,也可以手动赋值。

    @Test
/**
* 使用注解注入属性
*/
public void testUserService() {
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
UserService service = (UserService)context.getBean("userService");
service.print();
}

4.注解和xml结合使用

当然我们也可以同时使用注解和xml,一般我们在xml中实例化Bean,使用注解为属性赋值。


Spring@Autowired注解与自动装配

1   配置文件的方法

我们编写spring 框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量。并且要配套写上 get 和 set方法。

Boss 拥有 Office 和 Car 类型的两个属性:   
  
清单 3. Boss.java

[java] view plain copy

 
 
 
  1. package com.baobaotao;
  2. public class Boss {
  3. private Car car;
  4. private Office office;
  5. // 省略 get/setter
  6. @Override
  7. public String toString() {
  8. return "car:" + car + "/n" + "office:" + office;
  9. }
  10. }

System.out.println必须实现toString方法
  
我们在 Spring 容器中将 Office 和 Car 声明为 Bean,并注入到 Boss Bean 中:下面是使用传统 XML 完成这个工作的配置文件 beans.xml:   
  
清单 4. beans.xml 将以上三个类配置成 Bean

[xhtml] view plain copy

 
 
 
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  6. <bean id="boss" class="com.baobaotao.Boss">
  7. <property name="car" ref="car"/>
  8. <property name="office" ref="office" />
  9. </bean>
  10. <bean id="office" class="com.baobaotao.Office">
  11. <property name="officeNo" value="002"/>
  12. </bean>
  13. <bean id="car" class="com.baobaotao.Car" scope="singleton">
  14. <property name="brand" value=" 红旗 CA72"/>
  15. <property name="price" value="2000"/>
  16. </bean>
  17. </beans>

当我们运行以下代码时,控制台将正确打出 boss 的信息:   
  
清单 5. 测试类:AnnoIoCTest.java

[java] view plain copy

 
 
 
  1. import org.springframework.context.ApplicationContext;
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;
  3. public class AnnoIoCTest {
  4. public static void main(String[] args) {
  5. String[] locations = {"beans.xml"};
  6. ApplicationContext ctx =
  7. new ClassPathXmlApplicationContext(locations);
  8. Boss boss = (Boss) ctx.getBean("boss");
  9. System.out.println(boss);
  10. }
  11. }

这说明 Spring 容器已经正确完成了 Bean 创建和装配的工作。

2   @Autowired

Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。

要实现我们要精简程序的目的。需要这样来处理: 
* 在applicationContext.xml中加入:

[c-sharp] view plain copy

 
 
 
  1. <!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->
  2. <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

  Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。

* 修改在原来注入spirng容器中的bean的方法。 
     在域变量上加上标签@Autowired,并且去掉 相应的get 和set方法

  清单 6. 使用 @Autowired 注释的 Boss.java

[java] view plain copy

 
 
 
  1. package com.baobaotao;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. public class Boss {
  4. @Autowired
  5. private Car car;
  6. @Autowired
  7. private Office office;
  8. }

* 在applicatonContext.xml中 把原来 引用的<porpery >标签也去掉。

[xhtml] view plain copy

 
 
 
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  6. <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->
  7. <bean class="org.springframework.beans.factory.annotation.
  8. AutowiredAnnotationBeanPostProcessor"/>
  9. <!-- 移除 boss Bean 的属性注入配置的信息 -->
  10. <bean id="boss" class="com.baobaotao.Boss"/>
  11. <bean id="office" class="com.baobaotao.Office">
  12. <property name="officeNo" value="001"/>
  13. </bean>
  14. <bean id="car" class="com.baobaotao.Car" scope="singleton">
  15. <property name="brand" value=" 红旗 CA72"/>
  16. <property name="price" value="2000"/>
  17. </bean>
  18. </beans>

这样,当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。   
  
按照上面的配置,Spring 将直接采用 Java 反射机制对 Boss 中的 car 和 office 这两个私有成员变量进行自动注入。所以对成员变量使用 @Autowired 后,您大可将它们的 setter 方法(setCar() 和 setOffice())从 Boss 中删除。   
  
当然,您也可以通过 @Autowired 对方法或构造函数进行标注,如果构造函数有两个入参,分别是 bean1 和 bean2,@Autowired 将分别寻找和它们类型匹配的 Bean,将它们作为 CountryService (Bean1 bean1 ,Bean2 bean2) 的入参来创建 CountryService Bean。来看下面的代码:  对方法

[java] view plain copy

 
 
 
  1. package com.baobaotao;
  2. public class Boss {
  3. private Car car;
  4. private Office office;
  5. @Autowired
  6. public void setCar(Car car) {
  7. this.car = car;
  8. }
  9. @Autowired
  10. public void setOffice(Office office) {
  11. this.office = office;
  12. }
  13. }

这时,@Autowired 将查找被标注的方法的入参类型的 Bean,并调用方法自动注入这些 Bean。而下面的使用方法则对构造函数进行标注:

[java] view plain copy

 
 
 
  1. package com.baobaotao;
  2. public class Boss {
  3. private Car car;
  4. private Office office;
  5. @Autowired
  6. public Boss(Car car ,Office office){
  7. this.car = car;
  8. this.office = office ;
  9. }
  10. }

  由于 Boss() 构造函数有两个入参,分别是 car 和 office,@Autowired 将分别寻找和它们类型匹配的 Bean,将它们作为 Boss(Car car ,Office office) 的入参来创建 Boss Bean。

Spring注解:自动注入属性(@Resource、@Autowired、@Qualifier )

先写一个场景,举例说明:

1、接口:IAnimal

public Interface IAnimal{
......
}

2、实现类:DogImpl ,实现了IAnimal接口。

@Service("dogImpl")
public class DaoImpl impliments IAnimal{
...
}

3、业务类:AnimalController

public class AnimalController {
@Autowired
private IAnimal dogImpl;
......
}

  假如有一个“动物”的接口 IAnimal, DogImpl类实现了接口 IAnimal, 且该接口只有 DogImpl这一个实现类,那么在引用实现类的时候,我们使用的是实现类的接口(像上面程序展示的那样)。Spring会按 byType的方式寻找接口的实现类,将其注入。  
  假如有另一个实现类 CatImpl 也实现了接口 IAnimal, 这时候再按上面的方式去引用, 在同时存在两个实现类的情况下,会出现什么情况呢?

  答:会报错。 这是由于 @Autowired 的特性决定的: @Autowired 的注入方式是 byType 注入, 当要注入的类型在容器中存在多个时,Spring是不知道要引入哪个实现类的,所以会报错。

  那么在同一类型拥有多个实现类的时候,如何注入呢?

  答:这种场景下,只能通过 byName 注入的方式。可以使用 @Resource 或 @Qualifier 注解。

@Resource 默认是按照 byName 的方式注入的, 如果通过 byName 的方式匹配不到,再按 byType 的方式去匹配。所以上面的引用可以替换为:

public class AnimalController {
  @Resource(name="dogImpl") //实现类1中 @Service注解中标定的名称
  private IAnimal dogImpl;
  ......
}

@Qualifier 注解也是 byName的方式,但是与@Resource 有区别,@Qualifier 使用的是 类名。

public class AnimalController {
@Qualifier("DaoImpl") //实现类1的类名。注意区分与@Resource(name="dogImpl") 的区别。
private IAnimal dogImpl;
......
}

总结:
  1、@Autowired 是通过 byType 的方式去注入的, 使用该注解,要求接口只能有一个实现类。
  2、@Resource 可以通过 byName 和 byType的方式注入, 默认先按 byName的方式进行匹配,如果匹配不到,再按 byType的方式进行匹配。
  3、@Qualifier 注解可以按名称注入, 但是注意是 类名。

附:https://www.jianshu.com/p/80df0a6daf65

  https://blog.csdn.net/l1212xiao/article/details/80424064  

Spring之使用注解实例化Bean并注入属性的更多相关文章

  1. 编码实现Spring 利用@Resource注解实现bean的注入,xml实现基本数据类型的注入

    首先分析. 1: 肯定要利用dom4j读取xml配置文件,将所有的bean的配置信息读取出来 2: 利用反射技术,实例化所有的bean 3: 写注解处理器, 利用注解和内省实现依赖对象的注入. 4: ...

  2. Spring(三)实例化Bean以及注入对象

    使用xml实例化bean 在xml中实例化bean的三种方式 <bean id="springService" class="com.zhiyou100.crm.t ...

  3. 开涛spring3(12.2) - 零配置 之 12.2 注解实现Bean依赖注入

    12.2  注解实现Bean依赖注入 12.2.1  概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的 ...

  4. 注解实现Bean依赖注入

    12.2.1  概述 注解实现Bean配置主要用来进行如依赖注入.生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的数据将覆盖基于注解配置中的依赖注入的数 ...

  5. (转)Spring的三种实例化Bean的方式

    http://blog.csdn.net/yerenyuan_pku/article/details/52832793 Spring提供了三种实例化Bean的方式. 使用类构造器实例化. <be ...

  6. spring练习,使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打印输出。

    相关 知识 >>> 相关 练习 >>> 实现要求: 使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打印输出.要求如下: ...

  7. spring:为javabean的集合对象注入属性值

    spring:为JavaBean的集合对象注入属性值 在 spring 中可以对List.Set.Map 等集合进行配置,不过根据集合类型的不同,需要使用不同的标签配置对应相应的集合. 1.创建 Ts ...

  8. Spring入门之二-------SpringIoC之实例化Bean以及注入Bean

    一.实例化Bean 1. 通过默认构造方法实创建Bean public class Bean1 { public Bean1() { System.out.println(this.getClass( ...

  9. Spring 源码分析之 bean 依赖注入原理(注入属性)

         最近在研究Spring bean 生命周期相关知识点以及源码,所以打算写一篇 Spring bean生命周期相关的文章,但是整理过程中发现涉及的点太多而且又很复杂,很难在一篇文章中把Spri ...

随机推荐

  1. Win10离线安装.NET Framework 3.5的方法补充(附cab格式离线安装包下载) - 转载

    MS酋长很早以前已经分享了<Win10离线安装.NET Framework 3.5的方法技巧>,同时分享了exe格式的.NET Framework 3.5离线安装包下载地址.但有部分网友反 ...

  2. JDK5的新特性

    本篇博客内容 一.自动装箱和自动拆箱 二.泛型 三.增强for循环 四.静态导入 五.可变参数 六.枚举 一.自动装箱和自动拆箱  <=返回目录 java有8种基本数据类型  byte.shor ...

  3. EOF和~

    输入包含多组数据 while(~scanf("%d",&n))<=>  while(scanf("%d",&n)!=EOF)  

  4. 01-pandas基础-Series与DataFrame

    一.Series: 1,介绍:Series是以中类似于一维数组的对象,由一维数组以及与之相关的标签组成 特点:索引在左边,值在右边.在创建时,若我们未给数据指定索引,Series会自动创建一个0到N- ...

  5. [BZOJ2225][SPOJ2371]LIS2 - Another Longest Increasing Subsequence Problem:CDQ分治+树状数组+DP

    分析 这回试了一下三级标题,不知道效果怎么样? 回到正题,二维最长上升子序列......嗯,我会树套树. 考虑\(CDQ\)分治,算法流程: 先递归进入左子区间. 将左,右子区间按\(x\)排序. 归 ...

  6. mui初级入门教程(五)— 聊聊即时通讯(IM),基于环信 web im SDK

    文章来源:小青年原创发布时间:2016-06-15关键词:mui,环信 web im,html5+,im,页面传值,缓存转载需标注本文原始地址: http://zhaomenghuan.github. ...

  7. What does the dot after dollar sign mean in jQuery when declaring variables?

    https://stackoverflow.com/questions/22156664/what-does-the-dot-after-dollar-sign-mean-in-jquery-when ...

  8. React-Native 之 GD (六)无数据情况处理

    1.还是网络问题,在网络出现问题或者无法加载数据的时候,一般我们会展示空白页,在空白页中提示 无数据 之类的提示,比较好的还会使用 指示器 的方式告诉用户网络出现问题等等. 这边我们做以下处理,当无数 ...

  9. qcom Android Camera【转】

    本文转载自:http://blog.csdn.net/Wilsonboliu/article/details/54949196 1.总体架构 Android Camera 框架从整体上看是一个 cli ...

  10. qbzt day1 上午

    内容提要 模拟,贪心 在讲这些东西之前,我们先来了解一个东西:high level 这个东西大体上就是你做题之前要先想清楚自己要写什么,怎么写,然后再写,不要有一点写一点 1.模拟 模拟算法算是很水的 ...