四、Bean 的自动装配以及通过注解实现 Bean 的自动装配




一、Bean 的自动装配

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

    • 在xml中显式的配置:手动配置
    • 在java中显式配置:Java 代码配置
    • 隐式的自动装配bean【重要】:Bean 的自动装配

       在Spring框架中,Bean的自动装配是一种便捷的方式,用于将依赖关系自动注入到Bean中。通过自动装配,Spring可以根据一些规则自动将合适的Bean注入到其他Bean中,从而简化了开发过程。
  • Spring 提供的自动装配方式

    • 在配置文件 Bean.xml 中使用< bean >标签的 autowire 属性来指定自动装配的方式。例如,使用autowire="byName"来进行byName方式的自动装配。
  • Spring 提供的自动装配选项:

    • byName :byName 方式是根据 Bean 的名称进行装配

      • 代码示例
        • 实体类:Cat 、Dog、People

          public class Cat {
              public void cry(){
                  System.out.println("喵");
              }
          }
          
          public class Dog {
              public void cry(){
                  System.out.println("汪");
              }
          }
          
          public class People {
          
              private Cat cat;
              private Dog dog;
              private String name;
          
              public Cat getCat() { return cat;}
              public void setCat(Cat cat) {this.cat = cat;}
              public Dog getDog() {return dog;}
              public void setDog(Dog dog) { this.dog = dog;}
              public String getName() { return name;}
              public void setName(String name) {this.name = name;}
              
              @Override
              public String toString() {
                  return "People{" +
                          "cat=" + cat +
                          ", dog=" + dog +
                          ", name='" + name + '\'' +
                          '}';
              }
          }
          
        • Beans.sml

          <?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
                  https://www.springframework.org/schema/beans/spring-beans.xsd">
          
              <bean id="cat" class="com.sys.dto.Cat"/>
              <bean id="dog" class="com.sys.dto.Dog"/>
          
              <!-- 通过 autowire 属性指定 byName 自动装配方式-->
              <!-- byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的 bean id!
              注:需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致。否则会注入失败! -->
              <bean id="people" class="com.sys.dto.People" autowire="byName">
                   <property name="name" value="姚青"/>
               </bean>
          </beans>
          
        • 测试类

          public class MyTest {
          
              public static void main(String[] args) {
                  ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
                  People people = (People) context.getBean("people");
                  people.getCat().cry();
                  people.getDog().cry();
              }
          }
          
        • 测试结果:注入成功结果,以及 Bean 指定的 id 和实体类属性名不一致失败的结果
          在这里插入图片描述

          在这里插入图片描述

    • byType :byType 方式是根据 Bean 的类型进行装配

      • 代码示例:实体类、测试类不变,修改Beans.sml

        • Beans.sml

          <?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
                  https://www.springframework.org/schema/beans/spring-beans.xsd">
          
              <bean id="cat" class="com.sys.dto.Cat"/>
              <bean id="dog" class="com.sys.dto.Dog"/>
          
              <!-- 通过 autowire 属性指定 byType 自动装配方式-->
              <!-- byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
              注:需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致! -->
              <bean id="people" class="com.sys.dto.People" autowire="byType">
                   <property name="name" value="姚青"/>
               </bean>
          </beans>
          
        • 测试结果
          在这里插入图片描述
          当类型不唯一时,会提示报错
          在这里插入图片描述
          运行报错:No qualifying bean of type ‘com.sys.dto.Dog’ available: expected single matching bean but found 2: dog,dog2

  • 扩展

    • constructor :constructor 方式是通过构造函数进行装配

    • autodetect :autodetect 方式是根据 byType 和 constructor 两种方式进行自动装配




二、通过注解实现 Bean 的自动装配


       在通过 autowire 属性配置 Bean 的自动装配时,可能会存在漏配的情况,所以在 Spring 推出了使用注解实现 Bean 的自动装配。
       注:在JDK 1.5 版本和 Spring 2.5 版本之后就支持注解开发了。

  • Beans.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
    	        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>
    


2.1 @Autowired



  • @Autowired@Autowired 详细解释

    • @Autowired 可以直接作用在字段属性上,也可以在 set() 上,效果是一样的,但是放在字段属性上时,可以省略 set() 方法。

    • @Autowired 的属性:required

      • required = true:注入 bean 的时候该 bean 必须存在,不然就会注入失败!

      • required = false:注入 bean 的时候如果 bean 存在,就注入成功,如果没有就忽略跳过,启动不会报错!但是不能直接使用,因为该 Bean 为 NULL!

    • 搭配 @Autowired 使用的注解:@Qualifier

      • 因为 @Autowired 的自动装配装配方式是 byType,所以当同一种类型有多个 Bean ,并且 Bean 的 id 还和字段属性名不一致时,会出现无法匹配 Bean 的情况,这种时候就需要使用 @Qualifier(value = “xxx”) 去配置 @Autowired 的使用,指定一个唯一的bean对象注入!




  • 代码示例
    • 改造 Beans.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
      	        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/>
      
          <bean id="cat22" class="com.sys.dto.Cat"/>
          <bean id="cat33" class="com.sys.dto.Cat"/>
          <bean id="dog33" class="com.sys.dto.Dog"/>
          <bean id="people" class="com.sys.dto.People">
              <property name="name" value="姚青"/>
          </bean>
      </beans>
      
    • 改造 People 实体类,在cat、dog属性上添加 @Autowired 注解,并删除对应的 set()

      		public class People {
      		
      		    @Autowired
      		    @Qualifier(value = "cat22")//指定唯一的 Bean
      		    private Cat cat;
      		    
      		    @Autowired(required = false) // required = false时,允许注入的对象为空,否则不允许
      		    private Dog dog;
      		    
      		    private String name;
      		
      		    public Cat getCat() {return cat;}
      		    public Dog getDog() {return dog;}
      		    public String getName() {return name;}
      		    public void setName(String name) {this.name = name;}
      		
      		    @Override
      		    public String toString() {
      		        return "People{" +
      		                "cat=" + cat +
      		                ", dog=" + dog +
      		                ", name='" + name + '\'' +
      		                '}';
      		    }
      		}
      
    • 其余代码不变,运行结果
      在这里插入图片描述



2.2 @Resource



       @Resource注解,用于标记字段或方法,以便进行依赖注入。它与@Autowired注解类似,但功能略有不同。
  • @Resource注解有两种用法:

    • 标记字段:当@Resource注解标记在字段上时,它会告诉容器需要找到一个与字段名称相匹配的依赖项,并把 Bean 注入到字段给当中。容器将尝试按照名称来匹配依赖项,默认情况下,它将使用字段名作为依赖项的名称。如果找不到符合名称的匹配项,会继续匹配字段的类型,如果都没有匹配项,会抛出异常。

      • 代码示例:
        java
        public class MyClass {
            @Resource
            private MyDependency myDependency;
        }
        
    • 标记方法:当@Resource注解标记在方法上时,它会告诉容器要调用该方法,并将一个匹配的依赖项作为参数传递给该方法。类似字段的用法,默认情况下,它将使用方法名作为依赖项的名称。

      • 代码示例:

         @Resource
            public void setMyDependency(MyDependency myDependency) {
                this.myDependency = myDependency;
            }
        
  • @Resource注解还有一些可选属性,可以进一步指定依赖项的名称、类型和查找方式。例如:

    • name:指定依赖项的名称,用于与容器中的名称进行匹配。
    • type:指定依赖项的类型,用于与容器中的类型进行匹配。
    • lookup:指定依赖项的JNDI名称,用于在JNDI命名服务中查找依赖项。


2.3 @Resource 和 @Autowired的区别



相同点:

  • 都是用来自动装配的,都可以放在属性字段

不同点:

  • @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】

  • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】

  • 执行顺序不同:@Autowired通过byType的方式实现。

  • @Autowired是Spring框架的注解,而@Resource是Java的注解,前者不引用Spring无法使用,后者只要jdk版本是1.5版本以上就可以使用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值