【Spring】Spring中的Bean - 5、Bean的装配方式(XML、注解(Annotation)、自动装配)
阅读原文时间:2021年07月07日阅读:1

Bean的装配方式

简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean

文章目录

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

控制反转(IoC)是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

依赖注入

什么是Bean的装配?

​ Bean的装配方式是将Bean装配注入到Spring IoC容器中 ,Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配)。基于注解的装配方式尤其重要,它是当前的主流装配方式。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

Spring提供了两种基于XML的装配方式:设值注入(Setter Injection)和构造注入(Constructor Injection)。下面就讲解下如何在XML配置文件中使用这两种注入方式来实现基于XML的装配。

在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式调用setter方法来注入属性值。因此,设值注入要求一个Bean必须满足以下两点要求。

  • Bean类必须提供一个默认的无参构造方法。
  • Bean类必须为需要注入的属性提供对应的setter方法。

使用设值注入时,在Spring配置文件中,需要使用元素的子元素来为每个属性注入值;

而使用构造注入时,在配置文件里,需要使用元素的子元素来定义构造方法的参数,可以使用其value属性(或子元素)来设置该参数的值。

下面通过一个案例来演示基于XML方式的Bean的装配。

基于XML的装配,使用方式如下:

创建Java类,提供有参、无参构造以及属性setter方法;

(1)在chapter02模块的src/main/java目录下,创建一个com.awen.assemble包,在该包中创建User类,并在类中定义username、password和list集合三个属性及其对应的setter方法,如文件所示。文件 User.java

```java

package com.awen.assemble;

import java.util.List;

public class User {

private String username;

private Integer password;

private List list;

/**

* 1.使用构造注入

* 1.1提供带所有参数的有参构造方法。

_/

public User(String username, Integer password, List list) {

super();

this.username = username;

this.password = password;

this.list = list;

}

/_*

* 2.使用设值注入

* 2.1提供默认空参构造方法 ;

* 2.2为所有属性提供setter方法。

*/

public User() {

super();

}

public void setUsername(String username) {

this.username = username;

}

public void setPassword(Integer password) {

this.password = password;

}

public void setList(List list) {

this.list = list;

}

@Override

public String toString() {

return “User [username=” + username + “, password=” + password +

“, list=” + list + “]”;

}

}

```

在文件User.java中,由于要使用构造注入,所以需要其有参和无参的构造方法。同时,为了输出时能够看到结果,还重写了其属性的toString()方法。

(2)在src/main/resources目录下,创建Spring配置文件beans5.xm,创建配置文件beans5.xml,在配置文件中通过构造注入和设值注入的方式装配User类的实例,如文件所示。文件 beans5.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.使用构造注入方式装配User实例 -->
    <bean id="user1" class="com.awen.assemble.User">
        <constructor-arg index="0" value="柳小子" />
        <constructor-arg index="1" value="123456" />
        <constructor-arg index="2">
            <list>
                <value>"constructorvalue1"</value>
                <value>"constructorvalue2"</value>
            </list>
        </constructor-arg>
    </bean>
    <!--2.使用设值注入方式装配User实例 -->
    <bean id="user2" class="com.awen.assemble.User">
        <property name="username" value="子小柳"></property>
        <property name="password" value="654321"></property>
        <!-- 注入list集合 -->
        <property name="list">
            <list>
                <value>"setlistvalue1"</value>
                <value>"setlistvalue2"</value>
            </list>
        </property>
    </bean>
</beans>

在上述配置文件中,元素用于定义构造方法的参数,其属性index表示其索引(从0开始), value属性用于设置注入的值,其子元素来为User类中对应的list集合属性注入值。然后又使用了设值注入方式装配User类的实例,其中元素用于调用Bean实例中的setter方法完成属性赋值,从而完成依赖注入,而其子元素同样是为User类中对应的list集合属性注入值。

(3)在com.awen.assemble包中,创建测试类XmlBeanAssembleTest,在类中分别获取并输出配置文件中的user1和user2实例,如文件所示。文件 XmlBeanAssembleTest.java

package com.awen.assemble;
import org.springframework.context.ApplicationContext;
import
    org.springframework.context.support.ClassPathXmlApplicationContext;
public class XmlBeanAssembleTest {
    public static void main(String[] args) {

        // 加载配置文件
        ApplicationContext applicationContext =
                        new ClassPathXmlApplicationContext("beans5.xml");
        // 构造方式输出结果
        System.out.println(applicationContext.getBean("user1"));
        // 设值方式输出结果
        System.out.println(applicationContext.getBean("user2"));
    }
}

执行程序后,控制台的输出结果如下所示,

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=3035:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.assemble.XmlBeanAssembleTest
User [username=柳小子, password=123456, list=["constructorvalue1", "constructorvalue2"]]
User [username=子小柳, password=654321, list=["setlistvalue1", "setlistvalue2"]]

Process finished with exit code 0

从运行结果可以看出,已经成功地使用基于XML装配的构造注入和设值注入两种方式装配了User实例。

OK , 到了现在 , 我们彻底不用再去程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !

思考

user 对象是谁创建的 ?

【 user 对象是由Spring创建的 】

user 对象的属性是怎么设置的 ?

【user 对象的属性是由Spring容器设置的 】

这个过程就叫控制反转(IoC) :

控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的

反转 : 程序本身不创建对象 , 而变成被动的接收对象 .

依赖注入 : 就是利用set方法来进行注入的.

IOC是一种编程思想,由主动的编程变成被动的接收

可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .

除了通过设值注入(Setter Injection)和构造注入(Constructor Injection)实现IoC,还可以通过Spring提供的注解方法实现IoC,这也是企业开发过程中最常用的一种IoC实现方式。

在Spring中,尽管使用XML配置文件可以实现Bean的装配工作,但如果应用中有很多Bean时,会导致XML配置文件过于臃肿,给后续的维护和升级工作带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。

Spring中定义了一系列的注解,常用的注解如下所示。

  • @Component:可以使用此注解描述Spring中的Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
  • @Repository:用于将数据访问层(DAO层)的类标识为Spring中的Bean,其功能与@Component相同。
  • @Service:通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同。
  • @Controller:通常作用在控制层(如Spring MVC的Controller),用于将控制层的类标识为Spring中的Bean,其功能与@Component相同。
  • @Autowired:用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作。默认按照Bean的类型进行装配。
  • @Resource:其作用与Autowired一样。其区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按实例名称进行装配;如果指定type属性,则按Bean类型进行装配;如果都不指定,则先按Bean实例名称装配,如果不能匹配,再按照Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException异常。
  • @Qualifier:与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。在上面几个注解中,虽然@Repository、@Service与@Controller功能与@Component注解的功能相同,但为了使标注类本身用途更加清晰,建议在实际开发中使用@Repository、@Service与@Controller分别对实现类进行标注

下面,通过一个案例来演示如何通过这些注解来装配Bean。

(1)在chapter02模块的src/main/java目录下,创建一个com.awen.annotation包,在该包中创建接口UserDao,并在接口中定义一个save()方法,如文件所示。文件 UserDao.java

package com.awen.annotation;
public interface UserDao {
    public void save();
}

(2)在com.awen.annotation包中,创建UserDao接口的实现类UserDaoImpl,该类需要实现接口中的save()方法,如文件所示。文件 UserDaoImpl.java

package com.awen.annotation;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImpl implements UserDao{
   public void save(){
      System.out.println("userdao...save...");
   }
}

在文件UserDaoImpl.java中,首先使用@Repository注解将UserDaoImpl类标识为Spring中的Bean,其写法相当于配置文件中<bean id="userDao" class="com.awen.annotation.UserDaoImpl"/>的编写。然后在save()方法中输出打印一句话,用于验证是否成功调用了该方法。

(3)在com.awen.annotation包中,创建接口UserService,在接口中同样定义一个save()方法,如文件所示。文件UserService.java

package com.awen.annotation;
public interface UserService {
    public void save();
}

(4)在com.awen.annotation包中,创建UserService接口的实现类UserServiceImpl,该类需要实现接口中的save()方法,如文件所示。文件 UserServiceImpl.java

package com.awen.annotation;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService{
    @Resource(name="userDao")
    private UserDao userDao;
    public void save() {
         //调用userDao中的save方法
        this.userDao.save();
        System.out.println("userservice....save...");
    }

}

在文件 UserServiceImpl.java中,首先使用@Service注解将UserServiceImpl类标识为Spring中的Bean,这相当于配置文件中<bean id="userService" class="com.itheima.annotation.UserServiceImpl"/>的编写;然后使用@Resource注解标注在属性userDao上,这相当于配置文件中<property name="userDao" ref="userDao"/>的写法;最后在该类的save()方法中调用userDao中的save()方法,并输出一句话。

(5)在com.awen.annotation包中,创建控制器类UserController,编辑后如文件所示。文件UserController.java

package com.awen.annotation;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
@Controller("userController")
public class UserController {
    @Resource(name="userService")
    private UserService userService;
    public void save(){
        this.userService.save();
        System.out.println("userController...save...");
    }

}

在文件UserController.java中,首先使用@Controller注解标注了UserController类,这相当于在配置文件中编写<bean id="userController" class="com.itheima.annotation.UserController"/>;然后使用了@Resource注解标注在userService属性上,这相当于在配置文件中编写<property name="userService" ref="userService" />;最后在其save()方法中调用了userService中的save()方法,并输出一句话。

(6)在src/main/resources目录下,创建配置文件beans6.xml,在配置文件中编写基于Annotation装配的代码,如文件所示。文件 beans6.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 命名空间 ,在配置文件中开启相应的注解处理器 -->
     <context:annotation-config />
     <!--分别定义3个Bean实例  -->
     <bean id="userDao" class="com.awen.annotation.UserDaoImpl" />
      <bean id="userService"
          class="com.awen.annotation.UserServiceImpl" />
      <bean id="userController"
          class="com.awen.annotation.UserController" />

</beans>

从上述代码可以看出,文件beans6.xml与之前的配置文件有很大不同。首先,在元素中,增加了第4行,第7行和第8行中包含有context的约束信息;然后通过配置来开启注解处理器;最后分别定义了3个Bean对应所编写的3个实例。与XML装备方式有所不同的是,这里不再需要配置子元素<property>

上述Spring配置文件中的注解方式虽然较大程度简化了XML文件中Bean的配置,但仍需要在Spring配置文件中一一配置相应的Bean,为此Spring注解提供了另外一种高效的注解配置方式(对包路径下的所有Bean文件进行扫描),其配置方式如下。

<context:component-scan base-package="Bean所在的包路径" />

所以可以将上述文件文件 beans6.xml中第9~16行代码进行如下替换(推荐)。

<!--使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析-->
  <context:component-scan base-package="com.awen.annotation" />

(7)在com.awen.annotation包中,创建测试类AnnotationAssembleTest,在类中编写测试方法并定义配置文件的路径,然后通过Spring容器加载配置文件并获取UserController实例,最后调用实例中的save()方法,如文件所示。文件 AnnotationAssembleTest.java

package com.awen.annotation;
import org.springframework.context.ApplicationContext;
import
   org.springframework.context.support.ClassPathXmlApplicationContext;
public class AnnotationAssembleTest {
    public static void main(String[] args) {
        // 定义配置文件路径
        String xmlPath = "com/awen/annotation/beans6.xml";
        // 加载配置文件
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext(xmlPath);
        // 获取UserController实例
        UserController userController =
          (UserController) applicationContext.getBean("userController");
        // 调用UserController中的save()方法
        userController.save();
    }
}  

总是出错 一叶障目

执行程序后,控制台的输出结果如图所示。

userdao...save...
userservice....save...
userController...save...

从运行结果可以看到,Spring容器已成功获取了UserController的实例,并通过调用实例中的方法执行了各层中的输出语句,这说明已成功实现了基于Annotation装配Bean

小提示上述案例中如果使用@Autowired注解替换@Resource注解,也可以达到同样的效果。

提示: 除了可以像示例中通过元素来配置Bean外,还可以通过包扫描的形式来配置一个包下的所有Bean:

虽然使用注解的方式装配Bean,在一定程度上减少了配置文件中的代码量,但是也有企业项目中,是没有使用注解方式开发的,那么有没有什么办法既可以减少代码量,又能够实现Bean的装配呢?答案是肯定的,Spring的元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。所谓自动装配,就是将一个Bean自动地注入到其他Bean的Property中。autowire属性有5个值,其值及说明如表所示。表元素的autowire属性值及说明

​ 自动装配,使用方式如下:

修改上一节UserServiceImple和UserController,分别增加类属性的setter方法;

修改Spring配置文件beans6.xml,将配置文件修改成自动装配形式,也就是使用autowire属性配置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"
      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 命名空间 ,在配置文件中开启相应的注解处理器 -->
<!--      <context:annotation-config />-->
<!--     &lt;!&ndash;分别定义3个Bean实例  &ndash;&gt;-->
<!--      <bean id="userDao" class="com.awen.annotation.UserDaoImpl" />-->
<!--      <bean id="userService"-->
<!--          class="com.awen.annotation.UserServiceImpl" />-->
<!--      <bean id="userController"-->
<!--          class="com.awen.annotation.UserController" />-->

    <!--使用 context 命名空间 ,通知Spring扫描指定包下所有Bean类,进行注解解析-->
<!--     <context:component-scan base-package="com.awen.annotation" />-->

    <!-- 使用bean元素的autowire属性完成自动装配 -->
    <bean id="userDao"
        class="com.awen.annotation.UserDaoImpl" />
    <bean id="userService"
      class="com.awen.annotation.UserServiceImpl" autowire="byName" />
    <bean id="userController"
      class="com.awen.annotation.UserController" autowire="byName"/>
</beans>

上述配置文件中,用于配置userService和userController的元素中除了id和class属性外,还增加了autowire属性,并将其属性值设置为byName。在默认情况下,配置文件中需要通过ref来装配Bean,但设置了autowire="byName"后,Spring会自动寻找userService Bean中的属性,并将其属性名称与配置文件中定义的Bean做匹配。由于UserServiceImpl中定义了userDao属性及其setter方法,这与配置文件中id为userDao的Bean相匹配,所以Spring会自动地将id为userDao的Bean装配到id为userService的Bean中。执行程序后,控制台的输出结果如下所示。 从运行结果可以看出,使用自动装配同样完成了依赖注入

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=5574:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.annotation.AnnotationAssembleTest
userdao...save...
userservice....save...
userController...save...

Process finished with exit code 0

手动装配

自动装配

  • 自动装配是Spring满足bean依赖的一种方式!
  • Spring会在上下文中自动寻找,并自动给bean装配属性!

在Spring中有三种装配的方式:

  1. 在xml中显式配置;
  2. 在java中显式配置;
  3. 隐式的自动装配bean 重要

Autowired 自动装配

ByName自动装配

ByType自动装配

小结:

  • byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
  • byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!

使用注解实现自动装配

jdk1.5支持注解,Spring2.5开始支持注解。

要使用注解须知:

  1. 导入约束:context约束。

  2. 配置注解的支持:context:annot-config/

    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    &lt;context:annotation-config/&gt;
    </beans>

@Autowired

直接在属性上使用即可!也可以在set方式上使用!

使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IoC(Spring)容器中存在,且符合名字byName!

科普:

@Nullable    字段标记了这个注解,说明这个字段可以为null
    public People(@Nullable String name){
    this.name = name;
}


public @interface Autowired {
    boolean required() default true;
}

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解@Autowired完成的时候,我们可以使用@Qualifier(value=“xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!

@Resource注解

小结:

@Resource和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上;
  • @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】
  • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!
  • 执行顺序不同:@Autowired通过byType的方式实现,@Resource默认通过byName的方式实现。

在spring4之后,要使用注解开发,必须要保证aop的包导入了。

使用注解需要导入context约束,增加注解的支持!

<!--指定要扫描的包,这个包下的注解会生效-->
<context:component-scan base-package="com.kuang.pojo"/>
  1. bean

  2. 属性如何注入

    //等价于<bean id="user" class="com.kuang.pojo.User"/>
    //@Component 组件
    @Component
    public class User {
        //相当于<property name="name" value="小憨批"/>
        public String name;
        @Value("小憨批")
        public void setName(String name){
            this.name = name;
        }
    }
  3. 衍生的注解

    @Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!

    • dao【@Repository】
    • service【@Service】
    • controller【@Controller】

    这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean!

  4. 自动装配

    -@Autowired:自动装配通过类型,名字
        如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value="xxx")
    -@Nullable:字段标记了这个注解,说明这个字段可以为null
    -@Resource:自动装配通过名字,类型
  5. 作用域

    @Scope("singleton")
    public class User {
        //相当于<property name="name" value="小憨批"/>
        public String name;
        @Value("小憨批")
        public void setName(String name){
            this.name = name;
        }
    }
  6. 小结

    xml与注解:

    • xml更加万能,适用于任何场合!维护简单方便。
    • 注解,不是自己的类使用不了,维护相对复杂!

    xml与注解最佳实践:

    • xml用来管理bean;

    • 注解只负责完成属性的注入;

    • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持。