zoukankan      html  css  js  c++  java
  • 【Spring】Spring中的Bean

    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的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

    基于XML的装配

    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:Environmentsjdk-11.0.2injava.exe -javaagent:D:JavaideaIU-2019.2.winlibidea_rt.jar=3035:D:JavaideaIU-2019.2.winin -Dfile.encoding=UTF-8 -classpath D:IdeaProjectsJavaEE-enterprise-application-development-tutorialchapter02	argetclasses;D:Environmentsapache-maven-3.6.2maven-repojavaxannotationjsr250-api1.0jsr250-api-1.0.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-webmvc5.2.3.RELEASEspring-webmvc-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-aop5.2.3.RELEASEspring-aop-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-beans5.2.3.RELEASEspring-beans-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-context5.2.3.RELEASEspring-context-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-core5.2.3.RELEASEspring-core-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-jcl5.2.3.RELEASEspring-jcl-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-expression5.2.3.RELEASEspring-expression-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-web5.2.3.RELEASEspring-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去浏览一下底层源码 .

    基于注解(Annotation)的装配

    除了通过设值注入(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的约束信息;然后通过配置<context:annotation-config />来开启注解处理器;最后分别定义了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:

    <context:component-scan base-package=“com.awen.annotation” />

    自动装配

    虽然使用注解的方式装配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:Environmentsjdk-11.0.2injava.exe -javaagent:D:JavaideaIU-2019.2.winlibidea_rt.jar=5574:D:JavaideaIU-2019.2.winin -Dfile.encoding=UTF-8 -classpath D:IdeaProjectsJavaEE-enterprise-application-development-tutorialchapter02	argetclasses;D:Environmentsapache-maven-3.6.2maven-repojavaxannotationjsr250-api1.0jsr250-api-1.0.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-webmvc5.2.3.RELEASEspring-webmvc-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-aop5.2.3.RELEASEspring-aop-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-beans5.2.3.RELEASEspring-beans-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-context5.2.3.RELEASEspring-context-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-core5.2.3.RELEASEspring-core-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-jcl5.2.3.RELEASEspring-jcl-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-expression5.2.3.RELEASEspring-expression-5.2.3.RELEASE.jar;D:Environmentsapache-maven-3.6.2maven-repoorgspringframeworkspring-web5.2.3.RELEASEspring-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">
      
          <context:annotation-config/>
      
      </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;
      • 注解只负责完成属性的注入;
      • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持。
       <!--指定要扫描的包,这个包下的注解会生效-->
      <context:component-scan base-package="com.awen"/>
      <context:annotation-config/>
      
  • 相关阅读:
    常见的HTTP状态码(HTTP Status Code)说明
    Java基本数据类型和Integer缓存机制
    面向对象的三大基本特征和五大基本原则
    工程变更(ENGINEERING CHANGE)
    反射
    Redis学习手册(开篇)
    MVC,SSM与三层架构的构成及相互关系
    Java框架篇---Mybatis 入门
    java三大框架介绍
    WEB前端JS与UI框架
  • 原文地址:https://www.cnblogs.com/liuawen/p/12854071.html
Copyright © 2011-2022 走看看