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

本文详细介绍了如何通过Bean标签、注解、ComponentScan、Import导入、FactoryBean等不同方式向Spring容器中添加Bean,以及它们适用的场景和区别,帮助理解Spring组件化开发的多样性。
摘要由CSDN通过智能技术生成

内容来自【自学星球】

欢迎大家来了解我的星球,和星主(也就是我)一起学习 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方法
}

2)配置 spring-service.xml 文件

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

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);
    }
}

二、Bean注解形式

1)定义UserB实体

public class UserB {

    private Long id;

    private String name;

    public UserB() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }
    // 省略get,set方法
}

2)编写 StudySpringConfiguration 配置类

@Configuration
public class StudySpringConfiguration {

    @Bean
    public UserB userB() {
        UserB user = new UserB();
        user.setId(200L);
        user.setName("李四");
        return user;
    }
}

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);
    }
}

三、@ComponentScan + @Component 形式

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

@Service
public class UserServiceImpl {

    public UserServiceImpl() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }
}

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

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

这个与下面功能一样

@Configuration
@ComponentScan(value = "cn.j3code.studyspring")
public class StudySpringConfiguration {
}

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);
    }
}

四、@Import 导入形式

1)定义 UserBServiceImpl 实体

public class UserBServiceImpl  {

    public UserServiceImpl() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }
}

2)在配置类上加入 @Import

@Configuration
@Import(value = {UserBServiceImpl.class})
public class StudySpringConfiguration {
}

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);
    }
}

五、@Import + ImportSelector 接口形式

1)定义 UserCServiceImpl 实体

public class UserCServiceImpl   {

    public UserServiceImpl() {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }
}

2)编写 MyImportSelector 类实现 ImportSelector 接口

public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 将 Bean 的全限定类名传进入
        return new String[]{"cn.j3code.studyspring.service.UserCServiceImpl"};
    }
}

3)配指 @Import 注解

@Configuration
@Import(value = {MyImportSelector.class})
public class StudySpringConfiguration {
}

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);
    }
}

六、@Import + ImportBeanDefinitionRegistrar 接口形式

1)定义 UserC 实体

public class UserC {

    private Long id;

    private String name;

    public UserC () {
        System.out.println(this.getClass().getName() + " 中的空参构造器被调用...");
    }
    // 省略get,set方法
}

2)定义 MyImportBeanDefinitionRegistrar 类实现 ImportBeanDefinitionRegistrar 接口

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition("userC", new RootBeanDefinition(UserC.class));
    }
}

3)配指 @Import 注解

@Configuration
@Import(value = {MyImportBeanDefinitionRegistrar.class})
public class StudySpringConfiguration {
}

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);
    }
}

七、对比 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方法
}

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;
    }
}

4)配置 MyFactoryBean

@Configuration
public class StudySpringConfiguration {
    @Bean
    public MyFactoryBean myFactoryBean() {
        return new MyFactoryBean();
    }
}

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"));
    }
}

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

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


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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J3code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值