• Spring 中注入 Bean 的各种骚操作做


    内容来自【自学星球】

    欢迎大家来了解我的星球,和星主(也就是我)一起学习 Java ,深入 Java 体系中的所有技术。我给自己定的时间是一年,无论结果如何,必定能给星球中的各位带来点东西。

    想要了解更多,欢迎访问👉:自学星球

    --------------SSM系列源码文章及视频导航--------------

    创作不易,望三连支持!

    SSM源码解析视频

    👉点我

    Spring

    1. Spring 中注入 Bean 的各种骚操作做
    2. Spring 中Bean的生命周期及后置处理器使用
    3. Spring 中容器启动分析之refresh方法执行之前
    4. Spring refresh 方法分析之一
    5. Spring refresh 方法之二 invokeBeanFactoryPostProcessors 方法解析
    6. Spring refresh 方法分析之三
    7. Spring refresh 方法之四 finishBeanFactoryInitialization 分析
    8. Spring AOP源码分析一
    9. Spring AOP源码分析二
    10. Spring 事务源码分析

    SpringMVC

    1. SpringMVC 启动流程源码分析
    2. SpringMVC 请求流程源码分析

    MyBatis

    1. MyBatis 源码分析之 SqlSessionFactory 创建
    2. MyBatis 源码分析之 SqlSession 创建
    3. MyBatis 源码分析之 Mapper 接口代理对象生成及方法执行
    4. MyBatis 源码分析之 Select 语句执行(上)
    5. MyBatis 源码分析之 Select 语句执行(下)
    6. MyBatis 源码分析一二级缓存

    ---------------------【End】--------------------

    Spring中的世界,一切皆 Bean,那么就先介绍多种向 Spring 中添加 Bean 的方式。

    一、Bean 标签形式

    1)定义User实体

    public class User {
    
        private Long id;
    
        private String name;
    
        public User() {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
        // 省略get,set方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2)配置 spring-service.xml 文件

    <bean class="cn.j3code.studyspring.entity.User" name="user">
        <property name="id" value="100"/>
        <property name="name" value="张三"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4

    3)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            User bean = applicationContext.getBean(User.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、Bean注解形式

    1)定义UserB实体

    public class UserB {
    
        private Long id;
    
        private String name;
    
        public UserB() {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
        // 省略get,set方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2)编写 StudySpringConfiguration 配置类

    @Configuration
    public class StudySpringConfiguration {
    
        @Bean
        public UserB userB() {
            UserB user = new UserB();
            user.setId(200L);
            user.setName("李四");
            return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            UserB bean = applicationContext.getBean(UserB.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、@ComponentScan + @Component 形式

    1)定义 UserServiceImpl 实体,并加上 @Service 注解(他继承了 @Component 注解)

    @Service
    public class UserServiceImpl {
    
        public UserServiceImpl() {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2)配置文件 spring-service.xml 已经配置了包扫描标签

    <context:component-scan base-package="cn.j3code.studyspring"/>
    
    
    • 1
    • 2

    这个与下面功能一样

    @Configuration
    @ComponentScan(value = "cn.j3code.studyspring")
    public class StudySpringConfiguration {
    }
    
    • 1
    • 2
    • 3
    • 4

    3)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            UserServiceImpl bean = applicationContext.getBean(UserServiceImpl.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、@Import 导入形式

    1)定义 UserBServiceImpl 实体

    public class UserBServiceImpl  {
    
        public UserServiceImpl() {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2)在配置类上加入 @Import

    @Configuration
    @Import(value = {UserBServiceImpl.class})
    public class StudySpringConfiguration {
    }
    
    • 1
    • 2
    • 3
    • 4

    3)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            UserBServiceImpl bean = applicationContext.getBean(UserBServiceImpl.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    五、@Import + ImportSelector 接口形式

    1)定义 UserCServiceImpl 实体

    public class UserCServiceImpl   {
    
        public UserServiceImpl() {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2)编写 MyImportSelector 类实现 ImportSelector 接口

    public class MyImportSelector implements ImportSelector {
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            // 将 Bean 的全限定类名传进入
            return new String[]{"cn.j3code.studyspring.service.UserCServiceImpl"};
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3)配指 @Import 注解

    @Configuration
    @Import(value = {MyImportSelector.class})
    public class StudySpringConfiguration {
    }
    
    • 1
    • 2
    • 3
    • 4

    4)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            UserCServiceImpl bean = applicationContext.getBean(UserCServiceImpl.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    六、@Import + ImportBeanDefinitionRegistrar 接口形式

    1)定义 UserC 实体

    public class UserC {
    
        private Long id;
    
        private String name;
    
        public UserC () {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
        // 省略get,set方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2)定义 MyImportBeanDefinitionRegistrar 类实现 ImportBeanDefinitionRegistrar 接口

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            registry.registerBeanDefinition("userC", new RootBeanDefinition(UserC.class));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3)配指 @Import 注解

    @Configuration
    @Import(value = {MyImportBeanDefinitionRegistrar.class})
    public class StudySpringConfiguration {
    }
    
    • 1
    • 2
    • 3
    • 4

    4)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            UserC bean = applicationContext.getBean(UserC.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    七、对比 Bean 与 Import 导入的区别

    以上常规 Bean 的形式导入组件和 Import 形式导入组件有什么不一样,或者说 Import 形式导入用在什么场景。

    1、通常开发的时候用常规 Bean 的形式就可以了

    2、Import 形式导入只用于第三方组件导入,因为第三方类我们不能给其类上加 @Component 相关注解,所以若要使用第三方组件功能,就只能使用 Import 形式导入。

    3、这里的考虑是忽略了 xml 配置文件的形式导入,因为以后开发都基本是注解式开发

    八、FactoryBean 形式

    1)编写实体 UserD

    public class UserD {
    
        private Long id;
    
        private String name;
    
        public UserD () {
            System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
        }
        // 省略get,set方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2)编写 MyFactoryBean 并实现 FactoryBean 接口

    public class MyFactoryBean implements FactoryBean<UserD> {
        @Override
        public UserD getObject() throws Exception {
            UserD userD = new UserD();
            userD.setId(500L);
            userD.setName("j3code");
            return userD;
        }
    
        @Override
        public Class<?> getObjectType() {
            return UserD.class;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4)配置 MyFactoryBean

    @Configuration
    public class StudySpringConfiguration {
        @Bean
        public MyFactoryBean myFactoryBean() {
            return new MyFactoryBean();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3)测试

    public class StudySpringMain {
    
        public static void main(String[] args) {
            // 读取配置文件启动
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-service.xml");
    
            UserD bean = applicationContext.getBean(UserD.class);
            System.out.println(bean);
            System.out.println(applicationContext.getBean("myFactoryBean"));
            System.out.println(applicationContext.getBean("&myFactoryBean"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注:myFactoryBean 与 &myFactoryBean 获取 Bean 的区别

    好了,今天的内容到这里就结束了,我是 【J3】关注我,我们下期见


    • 由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。

    • 如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。

    • 感谢您的阅读,十分欢迎并感谢您的关注。

  • 相关阅读:
    基于java的家庭收支管理系统 计算机毕业设计
    韩顺平java课程527 -531速记笔记
    svg VS canvas,哪种在移动端适配度更好?实战经历告诉你~
    .NET Core之 ABP从入门到精通
    Java Keyword
    model.fit回调函数使用
    OpenCV单词轮廓检测
    在win11下安装mysql并通过python进行链接
    MySQL-函数
    Linux中sudo命令的添加和操作
  • 原文地址:https://blog.csdn.net/qq_40399646/article/details/126702582