当前位置: 澳门新濠3559 > 编程 > 正文

sanning的方式)上面的注解,测试 Test.java (输出订

时间:2019-10-07 13:11来源:编程
前言 Spring框架对Bean进行装配提供了很灵活的方式,下面归纳一下主要的方式:•在XML中进行显示配置• 在Java中进行显示配置• 隐式的bean发现机制和自动装配 sanning的方式)上面的注

前言

Spring框架对Bean进行装配提供了很灵活的方式,下面归纳一下主要的方式:• 在XML中进行显示配置• 在Java中进行显示配置• 隐式的bean发现机制和自动装配

sanning的方式)上面的注解,测试 Test.java (输出订单明细时。而自动装配实现就需要注解扫描,这时发现了两种开启注解扫描的方式,即<context:annotation-config/><context:component-scan>下面归纳一下这两种方式的异同点:

<context:annotation-config>:注解扫描是针对已经在Spring容器里注册过的Bean

<context:component-scan>:不仅具备<context:annotation-config>的所有功能,还可以在指定的package下面扫描对应的bean

Demo:

<context:annotation-config> 是用于激活那些已经在spring容器里注册过的bean(无论是通过xml的方式还是通过package sanning的方式)上面的注解,是一个注解处理工具。
<context:component-scan>除了具有<context:annotation-config>的功能之外,<context:component-scan>还可以在指定的package下扫描以及注册javabean 。

Spring的两种配置方式

采用注解的优势:

  • 注解可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。
  • 注解和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。

Demo:XML注册Bean方式

下面给出两个类,类A和类B

package com.test;pubic class B{ public B(){ System.out.println; }}

package com.test;public class A { private B bClass; public void setBClass{ this.bClass = bClass; System.out.println("通过set的方式注入B类"); } public A(){ System.out.println; }}

如何我们这时可以通过传统的xml配置在Application.xml里进行bean注册

<bean /><bean > <property name="bClass" ref="bBean"/></bean>

启动加载Application.xml

输出:类B类A通过set的方式注入B类

先看一个完全通过XML配置的例子,之后将它改成注解形式。有三个classA,B,C,并且B,C的对象被注入到A中。

1、基于注解的配置

配置类DoConfig

@Configuration
@ComponentScan("com.example")
public class DoAnnoConfig {

}

测试代码

   @Test
    public void test() {
        AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(DoAnnoConfig.class);
        LowerAction lowerAction=ctx.getBean(LowerAction.class);
        lowerAction.execute("Rod Johnson");
    }

测试结果

图片 1

测试结果


实验中想到的问题1:@ComponentScan的作用是什么?
@ComponentScan扫描包名下的所有类,把有注解声明的类加载到Spring容器中。
packages下用注解标识的类,由spring自动扫描并且装入bean容器。

实验中想到的问题2:既然@ComponentScan可以扫描包下的类并装入Bean容器,那么配置类上一定需要@Configuration注解吗?
@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法。
Spring提供了一个AnnotationConfigApplicanContext类,能够直接通过标注@Configuration的Java类启动Spring容器。

测试代码

    @Test
    public void test1(){
        AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(DoAnnoConfig.class);
    }

测试结果

图片 2

测试结果

由实验结果可见,Spring容器已启动。@Configuration作用为配置spring容器。因此必不可缺。


以前配置bean的方法及在bean之间建立依赖关系的做法

以用户购买商品为例主要有四个实体类(items,orderdateil,user)商品信息 Items.java

public class Items { private Integer id; private String name; private Float price; private String pic; private Date createtime; private String detail;//省略 get/setter @Override public String toString() { return "Items{"   ", name='"   name   '''   ", price="   price   ", pic='"   pic   '''   ", createtime="   createtime   ", detail='"   detail   '''   '}'; }}

订单明细(包含用户信息与商品信息) Orderdetail.java

public class Orderdetail { private int id; private Items items; private User user;//省略get/setter方法 @Override public String toString() { return "Orderdetail{"   ", items="   items   ", user="   user   '}'; } }

用户 User.jav

public class User { private Integer id; private String username; private Date birthday; private String sex;//省略get/setter方法 @Override public String toString() { return "User{"   ", username='"   username   '''   ", birthday="   birthday   ", sex='"   sex   '''   ", address='"   address   '''   ", iId="   iId   '}'; }}

在spring容器中我们将User和Order两个类声明为bean,并注入到Orderdetail这个bean中,因此创建一个bean.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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc"> <bean > <property name="name" value="苹果手机"></property> <property name="price" value="10000"></property> </bean> <bean > <property name="username" value="张三"></property> <property name="address" value="陝西西安"></property> </bean> <bean > <property name="items" ref="items"></property> <property name="user" ref="user"></property> </bean></beans>

测试 Test.java (输出订单明细时,成功时就会打印用户与商品的相关信息)

package test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import pojo.Orderdetail;/** * Created by admin on 2017/6/30. */public class Test { public static void main(String[] args) { String path = "bean.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext; Orderdetail orderdetail = (Orderdetail) applicationContext.getBean("orderdetail"); System.out.println(orderdetail); }}

图片 3图片.png

Demo:annotation配置注解开启方式

package com.test;pubic class B{ public B(){ System.out.println; }}

package com.test;public class A { private B bClass; @Autowired public void setBClass{ this.bClass = bClass; System.out.println("通过set的方式注入B类"); } public A(){ System.out.println; }}

然后我们需要在Application.xml里注册Bean,假如我们先这样配置,仅仅注册Bean,不开启扫描

<bean /><bean />

或者仅仅开启扫描,不注册Bean

<context:annotation-config/>

这时加载Application.xml配置

输出:类B类A

我们会发现下面的@Autowired的方法是不能被加载的

@Autowired public void setBClass{ this.bClass = bClass; System.out.println("通过set的方式注入B类"); }

解决方法:修改Application.xml配置文件

<context:annotation-config/><bean /><bean />

重新加载配置文件,输出正常了

输出:类B类A通过set的方式注入B类

归纳:<context:annotation-config>:注解扫描是针对已经在Spring容器里注册过的Bean

package com.xxx;  
public class B {  
  public B() {  
    System.out.println("creating bean B: "   this);  
  }  
}  

package com.xxx;  
public class C {  
  public C() {  
    System.out.println("creating bean C: "   this);  
  }  
}  

package com.yyy;  
import com.xxx.B;  
import com.xxx.C;  
public class A {   
  private B bbb;  
  private C ccc;  
  public A() {  
    System.out.println("creating bean A: "   this);  
  }  
  public void setBbb(B bbb) {  
    System.out.println("setting A.bbb with "   bbb);  
    this.bbb = bbb;  
  }  
  public void setCcc(C ccc) {  
    System.out.println("setting A.ccc with "   ccc);  
    this.ccc = ccc;   
  }  
}  

//在applicationContext.xml中加入下面的配置 :

<bean id="bBean"class="com.xxx.B"/>
<bean id="cBean"class="com.xxx.C"/>
<bean id="aBean"class="com.yyy.A">
  <property name="bbb" ref="bBean"/>
  <property name="ccc" ref="cBean"/>
</bean>


//加载applicationContext.xml配置文件,将得到下面的结果:

creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6

2、基于JAVA的配置

配置类DoJavaConfig

@Configuration
public class DoJavaConfig {
    @Bean(name = "UpperAction")
    public UpperAction upperAction(){
        return  new UpperAction();
    }
}

测试代码

  @Test
    public void test() {
        AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(DoJavaConfig.class);
        UpperAction upperAction=ctx.getBean(UpperAction.class);
        upperAction.execute("hahahaha");
    }

想到的问题1
@Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的<bean>。作用为注册bean对象。
既然@Bean的作用是注册bean对象,那么完全可以使用@Component、@Controller、@Service等注解注册bean,那么就需要配置@ComponentScan注解进行自动扫描。
那么基于JAVA的配置与基于注解的配置有什么区别呢?

图片 4

图1

图片 5

图2

图片 6

图3

实验中碰到的问题1:直接使用@Autowired注解修饰“Action”来注入Action,Spring容器报错

图片 7

报错

由于有多个类实现了Action接口,所以Spring不知道应该绑定哪个实现类,所以抛出了如上错误。
解决方法:

图片 8

解决方法

图片 9

使用Qualifier注解

实验中碰到的问题1:使用@Service注解修饰LowerAction和UpperAction,对于基于“Java配置”的方式是否是必须的?
不是必须的。@Service可以将一个类定义成一个bean,实例化并放入容器。而配置类中的@Bean把实例化的对象转化成一个Bean,放在IoC容器中。


使用 @Autowired 注释

  • @Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,这里必须明确:@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier[1]使用;
  • @Autowired标注可以放在成员变量上,也可以放在成员变量的set方法上。前者,Spring会直接将UserDao类型的唯一一个bean赋值给userDao这个成员变量;后者,Spring会调用setUserDao方法来将UserDao类型的唯一一个bean装配到userDao这个属性。
  • Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。

Demo:component配置注解开启方式

package com.test;pubic class B{ public B(){ System.out.println; }}

package com.test;@Componentpublic class A { private B bClass; @Autowired public void setBClass{ this.bClass = bClass; System.out.println("通过set的方式注入B类"); } public A(){ System.out.println; }}

然后我们配置一下application.xml,开启annotaion-config扫描

<context:annotation-config />

加载配置文件:

输出:类B类A

原因:<context:annotation-config>:注解扫描是针对已经在Spring容器里注册过的Bean,Bean并没有注册过,所以即使开启了@Autowired、@Component注解 和配置开启了annotaion-config扫描还是加载不到

修改配置文件:

<context:component-scan base-package="com.test"/>

重新加载配置文件:

输出:类B类A通过set的方式注入B类

归纳:

<context:annotation-config>:注解扫描是针对已经在Spring容器里注册过的Bean

<context:component-scan>:不仅具备<context:annotation-config>的所有功能,还可以在指定的package下面扫描对应的bean

<context:annotation-config /><context:component-scan>同时存在的时候,前者会被忽略。

即使注册Bean,同时开启<context:annotation-config />扫描,@autowire,@resource等注入注解只会被注入一次,也即只加载一次

接下来使用Autowired的方式将对象bbb和ccc注入到A中:
使用<context:annotation-config />:

3、结合前一章的两种注入方法输出hello

在之前的实验中
测试代码形式如下:

   @Test
    public void test() {
        AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(DoAnnoConfig.class);
        LowerAction lowerAction=ctx.getBean(LowerAction.class);
        lowerAction.execute("Rod Johnson");
    }

因为LowerAction的成员message均没有值,测试结果均如下:

图片 10

测试结果


因此可以通过以下方法输出hello

图片 11

通过@Value注解

图片 12

构造方法注入

图片 13

Setter()注入

使用@Autowired注释Orderdetail
  • Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。
  • 在bean.xml中 移除 boss Orderdetail 的属性注入配置的信息,并声明 AutowiredAnnotationBeanPostProcessor Bean。
<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean scope="singleton"> <property name="name" value="三星手机"></property> <property name="price" value="10000"></property> </bean> <bean > <property name="username" value="李四"></property> <property name="address" value="陝西西安"></property> </bean> <!-- 移除 boss Orderdetail 的属性注入配置的信息 --> <bean > </bean> <bean ></bean></beans>
  • 修改在原来注入spring容器中的bean的方法。在域变量上加上标签@Autowired,并且去掉 相应的get 和set方法

Orderdetail.java

package pojo;import org.springframework.beans.factory.annotation.Autowired;public class Orderdetail { private int id; @Autowired private Items items; @Autowired private User user; @Override public String toString() { return "Orderdetail{"   ", items="   items   ", user="   user   '}'; } public int getId() { return id; } public void setId { this.id = id; }}

用测试类测试:

图片 14图片.png

package com.yyy;  
import org.springframework.beans.factory.annotation.Autowired;  
import com.xxx.B;  
import com.xxx.C;  
public class A {   
  private B bbb;  
  private C ccc;  
  public A() {  
    System.out.println("creating bean A: "   this);  
  }  
  @Autowired  
  public void setBbb(B bbb) {  
    System.out.println("setting A.bbb with "   bbb);  
    this.bbb = bbb;  
  }  
  @Autowired  
  public void setCcc(C ccc) {  
    System.out.println("setting A.ccc with "   ccc);  
    this.ccc = ccc;  
  }  
}  

4、本章小结

Spring容器启动有三要素:Bean的定义,Bean的实现,Spring容器。
在基于XML的bean属性配置中,bean的定义信息与bean的实现类是分离的。

在 beans.xml 中配置两个 User类型的 Bean时

 <bean > <property name="username" value="李四"></property> <property name="address" value="陝西西安"></property> </bean> <bean > <property name="username" value="张三"></property> <property name="address" value="陝西西安"></property> </bean>

这样配置时,就会发生异常,因为Spring 容器将无法确定到底要用哪一个 Bean,Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名称,这样歧义就消除了。

 @Autowired @Qualifier private User user;
  • @Qualifier 中的 office 是 Bean 的名称,所以 @Autowired 和@Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。@Autowired 可以对成员变量、方法以及构造函数进行注释,而@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以 Spring 不将 @Autowired 和@Qualifier 统一成一个注释类。

然后,我们就可以从applicationContext.xml中移除下面的配置

使用 @Resource 注释

@Resource 的作用相当于 @Autowired,只不过 @Autowired 按 byType 自动注入,面@Resource 默认按 byName 自动注入罢了。@Resource 有两个属性是比较重要的,分别是 name 和 type,Spring 将@Resource 注释的 name 属性解析为 Bean 的名字,而 type 属性则解析为 Bean 的类型。所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不指定 name 也不指定 type 属性,这时将通过反射机制使用 byName 自动注入策略。

 // 自动注入类型为 Items 的 Bean @Resource private Items items; // 自动注入 bean 名称为 user 的 Bean @Resource(name = "user") private User user;
<property name="bbb" ref="bBean"/>
<property name="ccc" ref="cBean"/>

使用 <context:annotation-config/> 简化配置

Spring 2.1 添加了一个新的 context 的 Schema 命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。

而我们前面所介绍的 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 就是处理这些注释元数据的处理器。但是直接在 Spring 配置文件中定义这些 Bean 显得比较笨拙。Spring 为我们提供了一种方便的注册这些BeanPostProcessor 的方式,这就是 <context:annotation-config/>。

在bean.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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean scope="singleton"> <property name="name" value="三星手机"></property> <property name="price" value="10000"></property> </bean> <bean > <property name="username" value="李四"></property> <property name="address" value="陝西西安"></property> </bean> <bean > <property name="username" value="张三"></property> <property name="address" value="陝西西安"></property> </bean> <!-- 移除 boss Orderdetail 的属性注入配置的信息 --> <bean > </bean><!-- <!–@Autowired–> <bean ></bean> <!–@Resource–> <bean />--></beans>

<context:annotationconfig/> 将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。

在配置文件中使用 context 命名空间之前,必须在 <beans> 元素中声明 context 命名空间。

移除之后,我们的applicationContext.xml配置文件就简化为下面的样子了。因为注解本身并不能够做任何事情,它们只是最基本的组成部分,我们需要能够处理这些注解的处理工具来处理这些注解,这就是<context:annotation-config> 所做的事情。

使用 @Component

虽然我们可以通过 @Autowired 或 @Resource 在 Bean 类中使用自动注入功能,但是 Bean 还是在 XML 文件中通过 <bean> 进行定义 —— 也就是说,在 XML 配置文件中定义 Bean,通过@Autowired 或 @Resource 为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。能否也通过注释定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置呢?答案是肯定的,我们通过 Spring 2.5 提供的@Component 注释就可以达到这个目标了。

为什么 @Repository 只能标注在 DAO 类上呢?这是因为该注解的作用不只是将类识别为 Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。 Spring 本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。

Spring 2.5 在 @Repository 的基础上增加了功能类似的额外三个注解:@Component、@Service、@Constroller,它们分别用于软件系统的不同层次:

@Component 是一个泛化的概念,仅仅表示一个组件  ,可以作用在任何层次。@Service 通常作用在业务层,但是目前该功能与 @Component 相同。@Constroller 通常作用在控制层,但是目前该功能与 @Component 相同。

通过在类上使用 @Repository、@Component、@Service 和 @Constroller 注解,Spring 会自动创建相应的 BeanDefinition 对象,并注册到 ApplicationContext 中。这些类就成了 Spring 受管组件。这三个注解除了作用于不同软件层次的类,其使用方式与 @Repository 是完全相同的。

接下来完全使用注释定义 Bean 并完成 Bean 之间装配:

Items .java

package pojo;import org.springframework.stereotype.Component;import java.util.Date;@Component //使用 @Component 注释就可以将一个类定义为 Spring 容器中的 Beanpublic class Items { private Integer id; private String name; private Float price; private String pic; private Date createtime; private String detail; @Override public String toString() { return "Items{"   ", name='"   name   '''   ", price="   price   ", pic='"   pic   '''   ", createtime="   createtime   ", detail='"   detail   '''   '}'; }//省略get/set方法}

User.java

@Componentpublic class User { private Integer id; private String username; private Date birthday; private String sex; @Override public String toString() { return "User{"   ", username='"   username   '''   ", birthday="   birthday   ", sex='"   sex   '''   ", address='"   address   '''   ", iId="   iId   '}'; }

Orderdetail.java

package pojo;import javax.annotation.Resource;public class Orderdetail { private int id; // 自动注入类型为 Items 的 Bean @Resource private Items items; // 自动注入 bean 名称为 user 的 Bean @Resource(name = "user") private User user; @Override public String toString() { return "Orderdetail{"   ", items="   items   ", user="   user   '}'; } public int getId() { return id; } public void setId { this.id = id; }}

升级之后的配置文件beanUp.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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="pojo"/></beans>

这里,所有通过 <bean> 元素定义 Bean 的配置内容已经被移除,仅需要添加一行 <context:component-scan/> 配置就解决所有问题了——Spring XML 配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。<context:component-scan/> 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。

<context:annotation-config />
<bean id="bBean"class="com.xxx.B"/>
<bean id="cBean"class="com.xxx.C"/>
<bean id="aBean"class="com.yyy.A"/>

当我们加载applicationContext.xml配置文件之后,将得到下面的结果:

creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b

如果不加<context:annotation-config />只会得到

creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53

使用<context:component-scan>:

package com.xxx;  
import org.springframework.stereotype.Component;  
@Component  
public class B {  
  public B() {  
    System.out.println("creating bean B: "   this);  
  }  
}  

package com.xxx;  
import org.springframework.stereotype.Component;  
@Component  
public class C {  
  public C() {  
    System.out.println("creating bean C: "   this);  
  }  
}  

package com.yyy;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
import com.xxx.B;  
import com.xxx.C;  
@Component  
public class A {   
  private B bbb;  
  private C ccc;  
  public A() {  
    System.out.println("creating bean A: "   this);  
  }  
  @Autowired  
  public void setBbb(B bbb) {  
    System.out.println("setting A.bbb with "   bbb);  
    this.bbb = bbb;  
  }  
  @Autowired  
  public void setCcc(C ccc) {  
    System.out.println("setting A.ccc with "   ccc);  
    this.ccc = ccc;  
  }  
}  

applicationContext.xml配置文件修改为:

<context:annotation-config />

当我们加载applicationContext.xml配置文件之后,却没有任何输出,因为<context:annotation-config />仅能够在已经在已经注册过的bean上面起作用。对于没有在spring容器中注册的bean,它并不能执行任何操作。这时就需要<context:component-scan>,<context:component-scan>除了具有<context:annotation-config />的功能之外,还具有自动将带有@component,@service,@Repository等注解的对象注册到spring容器中的功能。

我们将applicationContext.xml配置文件作如下修改:

<context:component-scan base-package="com.xxx"/>

当我们加载applicationContext.xml的时候,会得到下面的结果:

creating bean B: com.xxx.B@1be0f0a
creating bean C: com.xxx.C@80d1ff

这是因为我们仅仅扫描了com.xxx包及其子包的类,而class A是在com.yyy包下,所以就扫描不到了

下面我们在applicationContext.xml中把com.yyy也加入进来:

<context:component-scan base-package="com.xxx,com.yyy"/>

然后加载applicationContext.xml就会得到下面的结果:

creating bean B: com.xxx.B@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9

这时applicationContext.xml文件已经简化为:

<context:component-scan base-package="com.xxx,com.yyy"/>

<context:component-scan>所产生的的处理那些注解的处理器工具,会处理所有绑定到容器上面的bean,不管是通过xml手动注册的还是通过scanning扫描注册的。

如果我们同时配置了<context:annotation-config />和<context:component-scan base-package="com.xxx" />,它们都具有处理在容器中注册的bean里面的注解的功能。会不会出现重复注入的情况呢?
在<context:annotation-config />和 <context:component-scan>同时存在的时候,前者会被忽略。也就是那些@autowire,@resource等注入注解只会被注入一次。

使用<mvc:annotation-driven/>:
不同于之前的两个注解来自于Spring,<mvc:annotation-driven/>来自于Spring MVC,对应的实现类是对应的实现类是org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
<mvc:annotation-driven/>标签可简化springmvc的相关配置,默认情况下其会创建并注册如下实例
1.RequestMappingHandlerMapping
2.BeanNameUrlHandlerMapping
3.RequestMappingHandlerAdapter
4.HttpRequestHandlerAdapter
5.SimpleControllerHandlerAdapter 等等。
没有<mvc:annotation-driven />的@Controller只是一个普通的Bean。 它不会绑定到传入的请求,它只是在应用程序上下文中挂起。

编辑:编程 本文来源:sanning的方式)上面的注解,测试 Test.java (输出订

关键词: 澳门新濠3559