Springbean的几种注入方式都了解吗?

本文详细介绍了Spring框架中Bean的三种注入方式:XML注入、注解注入和BeanDefinition注入。每种方式都有其特点和适用场景,XML注入适用于代码与配置分离,注解注入简化了配置过程,而BeanDefinition注入则是底层实现的基础。

Spring注入方式可以分为三类,xml注入、注解注入、BeanDefinition注入;用法上可以分为三种,但是底层实现代码都是统一BeanFactory,这三种也有联系xml注入和annotation注入都是依赖BeanDefinition扩展的接口,注解也是从xml过渡过来的,我们简单的看下这三种的写法。

XML注入

在springboot框架没有出来之前,xml配置被大量的使用,配置过程比较繁琐,但是对代码的侵入性较小,配置和代码分离操作。

实体定义

定义两个属性id,name,并实现get/set方法,重写toString方法,方便看打印结果。

public class UserXml {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{"  
                "id='"   id   '\''  
                ", name='"   name   '\''  
                '}';
    }
}

xml定义

在resources下新建目录META-INF下建spring-bean.xml文件,并填充对应的bean配置,bean需要配置id或者name值,IOC容器唯一即可,class配置定义的实体路径,对应的property设置初始化属性。

<?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="user" class="cn.cnzcb.spring.bean.UserXml">
        <property name="id" value="11"/>
        <property name="name" value="java圈"/>
    </bean>
</beans>

输出

创建一个BeanFactory对象,用ClassPathXmlApplicationContext实例化,简单说一下BeanFactory作为IOC容器的底层基础,可以说IOC容器就是BeanFactory,ClassPathXmlApplicationContext是IOC容器的功能扩展;ClassPathXmlApplicationContext需要传入资源文件的路径,在通过getBean方法获取具体的实体类,就是结果输出。

 //xml注入
        BeanFactory classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-bean.xml");
        UserXml userXml = classPathXmlApplicationContext.getBean(UserXml.class);
        System.out.println("userXml XML注入对象:"   userXml);

注解注入

注解是在spring2.0.3之后才出现的,大量应用也是在springboot的普及下,大家才慢慢接受。其主要好处就是操作简单,通过简单的注解就可以标识成bean组件,而且扩展了各种层次的注解,比如@Service、@Service、@Repository,都是基于@Component注解实现派生。

实体定义

实体通XML实体作用类似,这里新建一个类,用去区分不同的bean实现方式。

public class UserAnnotation {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{"  
                "id='"   id   '\''  
                ", name='"   name   '\''  
                '}';
    }

注解配置

正常情况下我们是通过标准注解@Configuration进行扫描注入,我们这里直接配置类即可,在这个类里面实例化bean组件,并进行初始化操作。

@Configuration
public class UserConfiguration {
    @Bean
    public UserAnnotation userAnnotation(){
        UserAnnotation userAnnotation = new UserAnnotation();
        userAnnotation.setId("11");
        userAnnotation.setName("java圈");
        return userAnnotation;
    }
}

输出

AnnotationConfigApplicationContext也是BeanFactory的一种实现,和ClassPathXmlApplicationContext功能类似,只是加载渠道不一样,把定义的配置类注册到IOC容器,调用register方法,这里需要注意,下一步需要调refresh方法就行bean的装载工作,然后通过getBean获取具体的实体,就行输出。

 //注解注入
        AnnotationConfigApplicationContext  annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(UserConfiguration.class);
        annotationConfigApplicationContext.refresh();
        UserAnnotation userAnnotation = annotationConfigApplicationContext.getBean(UserAnnotation.class);
        System.out.println("UserAnnotation注解注入" userAnnotation);

BeanDefinition注入

BeanDefinition是BeanFactory的底层实现,包括上面提到的方式,底层也是基于BeanDefinition实现的,一个bean组件对应一个BeanDefinition,但是实际操作过程中不会这个用,只是仅供参考。

实体定义

实体通XML实体作用类似,这里新建一个类,用去区分不同的bean实现方式。

public class UserBeanDefinition {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{"  
                "id='"   id   '\''  
                ", name='"   name   '\''  
                '}';
    }
}

输出

通过BeanDefinitionBuilder的genericBeanDefinition实例化一个构造器,传入的参数就是实体类,构建之后做初始化操作,之后BeanDefinition声明调用getBeanDefinition方法,通过getPropertyValues回去bean的具体参数进行结束输出。

//BeanDefinition注入
        BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserBeanDefinition.class);
        definitionBuilder.addPropertyValue("id", "11");
        definitionBuilder.addPropertyValue("name", "java圈");
        BeanDefinition beanDefinition = definitionBuilder.getBeanDefinition();
        String beanClassName = beanDefinition.getBeanClassName();
        MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
        String id = mutablePropertyValues.getPropertyValue("id").getValue().toString();
        String name = mutablePropertyValues.getPropertyValue("name").getValue().toString();
        System.out.println("BeanDefinition注入对象UserBeanDefition{id="   id ",name=" name "}");

结果输出

输出结果分别是xml注入、annotation注入,BeanDefinition注入。

userXml XML注入对象:User{id='11', name='java圈'}
UserAnnotation注解注入User{id='11', name='java圈'}
BeanDefinition注入对象UserBeanDefition{id=11,name=java圈}

源代码:https://github.com/itrickzhang/spring-demo

本文由博客一文多发平台 OpenWrite 发布!

<think>好的,用户想了解Spring框架中Bean注入的不同方法。我需要根据提供的引用内容来整理答案。首先,看看用户提供的四个引用,里面提到了几种注入方式,比如@Bean注解、工厂方法、配置类,还有控制加载顺序的问题。 首先,引用[1]和[2]提到了通过@Bean注解在配置类中声明Bean,包括处理参数注入的情况。引用[3]讨论了工厂方法,包括静态和非静态工厂的配置方式。引用[4]涉及Bean的加载顺序,这可能和依赖注入方式有关,但用户的问题主要是注入方法,所以可能需要重点放在前面的几种方式。 接下来,需要总结常见的Spring Bean注入方式。通常有构造器注入、Setter注入、字段注入,还有通过Java配置类(@Configuration和@Bean)、XML配置、组件扫描(@Component等注解)、工厂方法等。根据引用内容,用户提供的例子中有@Bean方法参数自动注入,比如test方法参数中的Wolf1Bean,这说明Spring支持在@Bean方法中使用参数自动注入依赖的Bean,这可能属于构造器注入的一种变种?或者是方法参数注入? 另外,引用[3]提到的工厂方法分为静态和非静态,非静态的需要先定义工厂Bean,然后通过factory-bean和factory-method来引用,而静态的则可以直接指定工厂类和方法。这部分需要详细说明。 用户的问题可能希望得到详细的步骤和不同方法的使用场景,比如什么时候用XML,什么时候用注解,或者工厂方法的应用场景。需要结合例子来解释每种方法,比如用代码示例说明@Bean的使用,或者@Component的方式。 另外,需要注意回答的结构,按照系统级指令,行内数学公式用$...$,但这里可能用不上数学公式。但需要确保LaTeX语法正确,不过问题不涉及数学,可能不需要。重点是中文回答,生成相关问题,并在引用处添加标识。 现在组织回答结构:首先分点介绍不同的注入方式,每种方式给出示例代码,并引用对应的引用内容。例如,构造器注入、Setter注入、字段注入、Java配置类、XML配置、工厂方法,可能还有注解自动装配如@Autowired。但根据提供的引用,可能重点在@Bean、工厂方法、参数注入等。 需要结合引用中的例子,比如引用[1]中的InterfaceInject2类,使用@Bean方法并带有参数,说明Spring会自动注入参数中的Bean。引用[2]中的@Bean(initMethod)示例,可能属于生命周期回调,但用户的问题是关于注入方式,所以可能这个例子不是直接相关,不过可以忽略。 引用[3]详细说明了工厂方法的配置,包括非静态和静态的情况,需要解释这两种情况如何配置,比如在XML中的配置方式,或者使用@Configuration类中的方法。 引用[4]关于Bean加载顺序,可能涉及到依赖注入时的顺序控制,比如使用@DependsOn注解,或者在配置类中的顺序,但用户的问题是注入方式,所以可能这部分可以作为相关问题的部分,或者在Bean依赖处理时提到。 总结可能的Bean注入方式: 1. 注解驱动的注入:使用@Component及其派生注解(@Service, @Repository等),结合@Autowired进行自动装配。 2. Java配置类:使用@Configuration和@Bean注解,在配置类中定义Bean,可以处理复杂的初始化逻辑,并支持方法参数注入。 3. XML配置:通过<bean>标签定义Bean,可以使用构造器参数或属性设置注入依赖。 4. 工厂方法注入:静态工厂和实例工厂方法,通过XML或Java配置指定工厂类和工厂方法。 5. 构造器注入:通过构造方法注入依赖,可以使用@Autowired注解或在XML中配置。 6. Setter注入:通过Setter方法注入,使用@Autowired或在XML中配置<property>。 7. 字段注入:直接在字段上使用@Autowired,但可能不推荐。 根据引用内容,可能需要详细说明Java配置类中的@Bean方法参数注入,如引用[1]中的例子,以及工厂方法的方式如引用[3]。同时,XML配置中的工厂方法配置可能也需要提及。 在回答时,每个方法需要给出代码示例,比如引用[1]中的代码展示@Bean方法参数自动注入Wolf1Bean,引用[3]中的工厂方法配置,可能需要在XML中的例子,但用户提供的引用中没有给出具体的XML示例,但可以描述。 需要确保每个引用在适当的地方被引用,比如当提到@Bean方法参数注入时,引用[1]作为例子,工厂方法部分引用[3],配置类中的@Bean引用[2]中的例子。 生成的相关问题可能需要包括不同注入方式的优缺点,如何选择,或者如何解决循环依赖,Bean的作用域等,但根据用户提供的引用,可能问题应围绕注入方式展开,如不同方式的区别,工厂方法的使用,参数注入的处理,加载顺序的影响等。 最后,整理回答的结构,分点详细说明每种方法,并添加引用标识,然后生成相关问题。</think>### Spring框架Bean注入方式详解 Spring框架提供多种Bean注入方式,适用于不同场景需求。以下是六种核心方法及实现示例: #### 一、注解驱动自动装配 通过组件扫描和自动装配实现: ```java @Component public class ServiceImpl { @Autowired // 字段注入 private Dao dao; @Autowired // 构造器注入(推荐) public ServiceImpl(Dao dao) { this.dao = dao; } @Autowired // setter注入 public void setDao(Dao dao) { this.dao = dao; } } ``` *特点*:需配合`@ComponentScan`启用扫描,构造器注入能保证不可变对象[^4]。 #### 二、Java配置类注入 使用`@Configuration`和`@Bean`声明: ```java @Configuration public class AppConfig { @Bean public DataSource dataSource() { return new HikariDataSource(); } @Bean public Service service(DataSource dataSource) { // 参数自动注入 return new ServiceImpl(dataSource); } } ``` *特点*:支持方法参数自动注入依赖[^1],适合复杂初始化场景。 #### 三、XML配置注入 传统XML配置方式: ```xml <bean id="userDao" class="com.dao.UserDaoImpl"/> <bean id="userService" class="com.service.UserService"> <constructor-arg ref="userDao"/> <!-- 构造器注入 --> <property name="cache" ref="redisCache"/> <!-- setter注入 --> </bean> ``` *特点*:显式声明依赖关系,便于集中管理配置[^3]。 #### 四、工厂方法注入 ##### 1. 静态工厂 ```java public class BeanFactory { public static Bean createBean() { return new SpecialBean(); } } ``` XML配置: ```xml <bean id="specialBean" class="com.BeanFactory" factory-method="createBean"/> ``` ##### 2. 实例工厂 ```java public class InstanceFactory { public Bean produce() { return new InstanceBean(); } } ``` XML配置: ```xml <bean id="factory" class="com.InstanceFactory"/> <bean id="instanceBean" factory-bean="factory" factory-method="produce"/> ``` *特点*:解耦对象创建过程[^3]。 #### 五、条件化装配 使用`@Conditional`实现动态装配: ```java @Bean @Conditional(DataSourceCondition.class) public DataSource dataSource() { // 根据条件创建不同数据源 } ``` #### 六、模块化装配 通过`@Import`整合配置: ```java @Configuration @Import({SecurityConfig.class, PersistenceConfig.class}) public class MainConfig { } ``` ### 选择策略对比 | 方式 | 适用场景 | 优势 | |---------------|----------------------------------|-----------------------| | 注解驱动 | 常规业务组件 | 简洁直观 | | Java配置类 | 第三方库集成 | 强类型检查 | | XML配置 | 遗留系统维护 | 集中管理 | | 工厂方法 | 复杂对象创建 | 创建逻辑封装 | ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值