• Bean的装配


    什么是bean的装配

    指的是用户将自己开发的Bean装配到Spring Ioc容器中

    Bean的装配方式1----在XML文件中显式装配

    1. 简易值的装配
      指的是一般数据类型的装配;比如说Integer、String等;可以参考上一篇博客
    2. 集合装配

    Set、Map、List、Array、Properties

     <bean id="favorite1" class="com.bean.Favorite">
            <property name="favoriteName" value="踢球"/>
        bean>
        <bean id="user1" class="com.bean.User">
            <property name="id" value="1"/>
            <property name="name" value="刘飞红"/>
            <property name="employee" value="总经理"/>
            <property name="favorite" ref="favorite1"/>
         bean>
    
    
    
        <bean id="special" class="com.bean.SpecialLoad" >
            <property name="set">
                <set>
                    <value>set-value1value>
                    <value>set-value3value>
                set>
            property>
    
            <property name="map">
                <map>
                    <entry key="map-key1" value="map-value1"/>
                    <entry key="map-key2" value="map-value2"/>
                map>
            property>
            <property name="list">
                <list>
                    <value>list-value-1value>
                    <value>list-value-2value>
                list>
            property>
            <property name="array">
                <array>
                    <value>array-value1value>
                    <value>array-value2value>
                array>
            property>
    
            <property name="properties">
                <props>
                    <prop key="prop1">prop-value-1prop>
                     <prop key="prop2">prop-value-2prop>
                props>
            property>
    
            <property name="userList" ref="user1"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    1. 命名空间的装配(一般不使用)

    在这里插入图片描述

             a、必须引入对应的命名空间和xml模式文件
             例如:
    	   
    	      
    		  
    		b、使用构造器注入 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Bean的装配方式2----使用@Component装配

    隐式Bean的发现机制和自动装配原则

    组件扫描:通过定义资源的方式,让Spring Ioc容器扫描对应的包从而把Bean装配进来

    最基础的扫描

    1. 使用@Component装配Bean
    package com.bean;
    
    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/8 20:58
     * @description:
     */
    
    @Data
    @Component(value = "role1")
    public class Role {
        @Value("1")
        private Integer id;
        @Value("张飞")
        private String name;
    
        @Value("部门经理")
        private String emp;
    
        public Role() {
        }
    
        public Role(Integer id, String name, String emp) {
            this.id = id;
            this.name = name;
            this.emp = emp;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    2.创建一个配置类,该类使用@ComponentScan注解告诉Ioc容器在什么地方扫描Bean@ComponentScan默认扫描当前包的路径(bean和配置类在同一个包才能扫描到)

    package com.bean;
    
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * @author Una
     * @date 2022/8/8 21:17
     * @description:默认扫描当前包的路径(bean和配置类在同一个包才能扫描到)
     */
    
    //@ComponentScan(basePackageClasses = {Role.class, RoleServiceImpl.class})//(basePackageClasses = {Role.class})可以省略
    @ComponentScan(basePackages = {"com.bean"})
    //可以扫描包也可以扫描类
    public class BuildRole {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 在使用时要用AnnotationConfigApplicationContext类去创建Ioc容器; 在创建Ioc容器时,要将定义的配置类的信息导入;调用getBean()获取
    package com.bean;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import static org.junit.Assert.*;
    
    /**
     * @author Una
     * @date 2022/8/8 21:15
     * @description:
     */
    public class RoleTest {
        @Test
        public void selectRole(){
            ApplicationContext cp=new AnnotationConfigApplicationContext(BuildRole.class);
    
            Role role=(Role) cp.getBean("role1");
            System.out.println(role);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    最终结果:
    在这里插入图片描述

    多文件时的扫描

    在很多时候,我们需要实现接口的方法;在方法中;我们使用对象。在这种情况下,往往需要多个文件来实现;bean文件、接口文件、接口实现文件;下面以Role为例使用ComponentScan:

    1. Role bean文件:
    package com.bean;
    
    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/8 20:58
     * @description:
     */
    
    @Data
    @Component(value = "role1")
    public class Role {
        @Value("1")
        private Integer id;
        @Value("张飞")
        private String name;
    
        @Value("部门经理")
        private String emp;
    
        public Role() {
        }
        public Role(Integer id, String name, String emp) {
            this.id = id;
            this.name = name;
            this.emp = emp;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    1. 接口文件RoleService:
    package com.service;
    
    import com.bean.Role;
    
    /**
     * @author Una
     * @date 2022/8/9 14:22
     * @description:
     */
    
    
    public interface RoleService {
        public void printRoleInfo(Role role);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 接口实现类
    import lombok.Data;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/9 14:23
     * @description:
     */
    @Data
    @Component
    public class RoleServiceImpl implements RoleService {
        
        @Override
        public void printRoleInfo(Role role) {
            System.out.println("["+role.getId()+";"+role.getName()+";"+role.getEmp()+"]");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 扫描文件
      值得注意的是;在扫描文件进行扫描时;需要扫描两个文件或者两个文件所在的包
    package com.bean;
    
    import com.impl.RoleServiceImpl;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * @author Una
     * @date 2022/8/8 21:17
     * @description:默认扫描当前包的路径(bean和配置类在同一个包才能扫描到)
     */
    
    //@ComponentScan(basePackageClasses = {Role.class, RoleServiceImpl.class})//(basePackageClasses = {Role.class})可以省略
    @ComponentScan(basePackages = {"com.bean","com.Impl"})
    public class BuildRole {
        //用RoleServiceImpl.class把Role.class扫描
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. 测试文件
      值得注意的是:在测试时必须使用 AnnotationConfigApplicationContext作为Ioc容器
    package com.service;
    
    import com.bean.BuildRole;
    import com.bean.Role;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import static org.junit.Assert.*;
    
    /**
     * @author Una
     * @date 2022/8/9 14:45
     * @description:
     */
    
    
    public class RoleServiceTest {
        @Test
        public  void getRole(){
            AnnotationConfigApplicationContext aa=new AnnotationConfigApplicationContext(BuildRole.class);
            Role role=aa.getBean(Role.class);
            RoleService roleService=aa.getBean(RoleService.class);
            roleService.printRoleInfo(role);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    Bean的装配方式3----使用@Autowired自动装配

    @Autowired需要配合@Component使用;@Autowired的含义是自动装配;它配合@Component扫描直接将bean注入;下面以Role为例

    实现一个接口的情况

    1. Role类
      在Role类中;使用@Component、@Value将Role配置完成
    package com.bean;
    
    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/8 20:58
     * @description:
     */
    
    @Data
    @Component(value = "role1")
    public class Role {
        @Value("1")
        private Integer id;
        @Value("张飞")
        private String name;
    
        @Value("部门经理")
        private String emp;
    
        public Role() {
        }
    
        public Role(Integer id, String name, String emp) {
            this.id = id;
            this.name = name;
            this.emp = emp;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    1. RoleService接口
      在接口中;除了方法;不需要进行别的操作
    package com.service;
    
    import com.bean.Role;
    
    /**
     * @author Una
     * @date 2022/8/9 14:22
     * @description:
     */
    
    
    public interface RoleService {
        public void printRoleInfo();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. RoleServiceImpl实现RoleService方法
      在RoleServiceImpl中;使用@Autowired将配置好的Role对象赋给role
    package com.impl;
    
    import com.bean.Role;
    import com.service.RoleService;
    import lombok.Data;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/9 14:23
     * @description:
     */
    @Data
    @Component
    public class RoleServiceImpl implements RoleService {
        @Autowired
        private Role role=null;
        @Override
        public void printRoleInfo() {
            System.out.println("["+role.getId()+";"+role.getName()+";"+role.getEmp()+"]");
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 扫描文件BuildRole
      可以扫描类文件也可以扫描包
    package com.bean;
    
    import com.impl.RoleServiceImpl;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * @author Una
     * @date 2022/8/8 21:17
     * @description:默认扫描当前包的路径(bean和配置类在同一个包才能扫描到)
     */
    
    //@ComponentScan(basePackageClasses = {Role.class, RoleServiceImpl.class})//(basePackageClasses = {Role.class})可以省略
    @ComponentScan(basePackages = {"com.bean","com.Impl"})
    public class BuildRole {
        //用RoleServiceImpl.class把Role.class扫描
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. RoleServiceTest测试结果
      在测试时;可以不再获得role
    package com.service;
    
    import com.bean.BuildRole;
    import com.bean.Role;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import static org.junit.Assert.*;
    
    /**
     * @author Una
     * @date 2022/8/9 14:45
     * @description:
     */
    
    
    public class RoleServiceTest {
        @Test
        public  void getRole(){
            AnnotationConfigApplicationContext aa=new AnnotationConfigApplicationContext(BuildRole.class);
            RoleService roleService=aa.getBean(RoleService.class);
            roleService.printRoleInfo();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    多次实现接口的情况

    自动装配的歧义性:Spring建议使用接口编程,每个接口都有一个实现类;但是,在实际开发中一个接口的实现类会有多个,此时自动装配时就有歧义;如果在每个类中都与上文自动注入方式类似;spring将无法识别;在这个时候;可以在原文件的基础上,加上注解@Primary
    @Primary:代表首要的,作用是告诉IoC容器,请优先使用该类注入

    import com.service.RoleService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/9 18:58
     * @description:
     */
    
    @Component
    @Primary
    public class RoleServiceImplThree implements RoleService {
        @Autowired
        private Role role=null;
        @Override
        public void printRoleInfo() {
            System.out.println("第三次实现:"+role.getName());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Bean的装配方式4----使用@Bean装配

    @Bean注解:可以用在方法上,方法返回的对象作为Spring的Bean。不能使用在类上

    package com.control;
    
    import com.bean.Role;
    import com.impl.RoleServiceImpl;
    import com.impl.RoleServiceImplTwo;
    import com.service.RoleService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Una
     * @date 2022/8/9 19:21
     * @description:
     */
    
    @Component
    public class RoleControl  {
        @Autowired
        @Qualifier(value = "RoleServiceImpl3")
        private RoleService roleService=null;
        public void getRole(){
            roleService.printRoleInfo();
        }
    
        @Bean(name = "RoleServiceImpl2")
        public  RoleService printRole(){
            System.out.println("role2");
            return new RoleServiceImplTwo();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    测试:

    package com.control;
    
    import com.bean.BuildRole;
    import com.impl.RoleServiceImplThree;
    import com.service.RoleService;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import static org.junit.Assert.*;
    
    /**
     * @author Una
     * @date 2022/8/9 19:25
     * @description:
     */
    
    
    public class RoleControlTest {
        @Test
        public void testRole(){
            AnnotationConfigApplicationContext aa=new AnnotationConfigApplicationContext(BuildRole.class);
            RoleControl rc=(RoleControl) aa.getBean(RoleControl.class);
            rc.getRole();
            rc.printRole();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述@Component注解和@Bean注解的区别:

    	    (a)@Component注解只能注解在类上,不能注解在方法上。
    	    	缺点:在java开发中需要使用第三方的包(jar)时,无法给这些包中的类使用@Component注解,若必须要用只能是新建一个类继承第三方包中的类;然后在自己新建的类上使用@Component注解,这就显的不伦不类。
    		   
    		(b)@Bean注解:不能使用在类上
    		
    		   @Bean(name = "roleServiceImpl1")
    		   
    		     'name':是一个字符串的数组,运行配置多个BeanName
    			 
    			 'autowire':标志是一个引用的Bean对象,默认为Autowire.NO
    			 
    			 'initMethod':自定义初始化方法
    			 
    			 'destroyMethod':自定义销毁方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    装配Bean的方式的比较:

      1、装配方式:
    
        (1)在XML文件中显式配置
    
        (2)在java的接口和类中实现配置
    
        (3)隐式Bean的发现机制和自动装配(使用注解)
    	
    2、装配方式的选择:
    
        (1)基于约定优于配置的原则,优先考虑隐式Bean的发现机制和自动装配原则。
        	优点:减少开发者的 决定权,简单又灵活
    		
    	(2)在没有办法使用自动装配时,优先考虑java接口和类中实现配置
    	
    	(3)若前面两种方法都无法实现时,使用xml方式进行配置	 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    电流继电器JDL-1002A
    HTML & CSS
    慢速排序算法到底有多慢
    【Hive-小文件合并】Hive外部分区表利用Insert overwrite的暴力方式进行小文件合并
    Django学习(三) 之 模板中标签的使用
    [ Linux 长征路第四篇 ] 开发工具 vim的使用 gcc/g++的使用
    如何安装虚拟机
    【保姆级】lookup-method标签实践与分析
    王道数据结构编程题 链表
    vue 项目的屏幕自适应方案
  • 原文地址:https://blog.csdn.net/m0_50744075/article/details/126235386