Spring注入Bean的几种方式

本文详细介绍了Spring框架中通过注解实现Bean注入的各种方法,包括通过@Configuration和@Bean注解配置Bean,通过@Component及其变形注解标记组件,利用@Autowired实现依赖注入等。
部署运行你感兴趣的模型镜像

通过注解注入Bean

背景

我们谈到Spring的时候一定会提到IOC容器、DI依赖注入,Spring通过将一个个类标注为Bean的方法注入到IOC容器中,达到了控制反转的效果。那么我们刚开始接触Bean的时候,一定是使用xml文件,一个一个的注入,就例如下面这样。

	<bean id="bean" class="beandemo.Bean" />
复制代码

我们的项目一般很大的话,就需要成千上百个Bean去使用,这样写起来就很繁琐。那么Spring就帮我们实现了一种通过注解来实现注入的方法。只需要在你需要注入的类前面加上相应的注解,Spring就会帮助我们扫描到他们去实现注入。

xml扫描包的方式

	<context:component-scan base-package="com.company.beandemo"/>
复制代码

通过注解注入的一般形式

一般情况下,注入Bean有一个最直白,最易懂的方式去实现注入,下面废话先不多说,先贴代码。


  • Bean类
	public class MyBean{
	}
复制代码
  • Configuration类
	//创建一个class配置文件
	@Configuration
	public class MyConfiguration{
		//将一个Bean交由Spring进行管理
        @Bean
        public MyBean myBean(){
            return new MyBean();
        }
	}
复制代码
  • Test类

与xml有一点不同,这里在Test中,实例化的不再是ClassPathXmlApplicationContext,而是获取的AnnotationConfigApplicationContext实例。

	ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
	MyBean myBean = cotext.getBean("myBean",MyBean.class);
	System.out.println("myBean = " + myBean);
复制代码

上面的代码中MyBean也就是我们需要Spring去管理的一个Bean,他只是一个简单的类。而MyConfiguration中,我们首先用@Configuration注解去标记了该类,这样标明该类是一个Spring的一个配置类,在加载配置的时候会去加载他。

在MyConfiguration中我们可以看到有一个方法返回的是一个MyBean的实例,并且该方法上标注着@Bean的注解,标明这是一个注入Bean的方法,会将下面的返回的Bean注入IOC。

通过构造方法注入Bean

我们在生成一个Bean实例的时候,可以使用Bean的构造方法将Bean实现注入。直接看代码


  • Bean类
	@Component
	public class MyBeanConstructor {

    	private AnotherBean anotherBeanConstructor;

    	@Autowired
    	public MyBeanConstructor(AnotherBean anotherBeanConstructor){
     	   this.anotherBeanConstructor = anotherBeanConstructor;
    	}

    	@Override
    	public String toString() {
        	return "MyBean{" +
            	"anotherBeanConstructor=" + anotherBeanConstructor +
            	'}';
    	}
	}
复制代码
  • AnotherBean类
	@Component(value="Bean的id,默认为类名小驼峰")
	public class AnotherBean {
	}
复制代码
  • Configuration类
	@Configuration
	@ComponentScan("com.company.annotationbean")
	public class MyConfiguration{
	}
复制代码

这里我们可以发现,和一般方式注入的代码不一样了,我们来看看新的注解都是什么意思:

  • @AutoWired

简单粗暴,直接翻译过来的意思就是自动装配:wrench:,还不理解为什么叫自动装配:wrench:?看了下一个注解的解释你就知道了。若是在这里注入的时候指定一个Bean的id就要使用@Qualifier注解

  • @Component(默认单例模式)

什么??这翻译过来是零件,怎么感觉像是修汽车??是的,Spring管理Bean的方法就是修汽车的方式。我们在需要将一个类变成一个Bean被Spring可以注入的时候加上注解零件@Conmonent,那么我们就可以在加载Bean的时候把他像零件一样装配:wrench:到这个IOC汽车上了

在这里我们还有几个其他的注解也可以实现这个功能,也就是细化的@Component:

    • @Controller 标注在Controller层
    • @Service 标注在Service层
    • @Repository 标注在dao层
  • @ComponentScan("")

还是翻译,零件扫描,我们去看看括号里的“零件仓库”里面,哪些“零件”(类)需要被装载,Spring就会去扫描这个包,将里面所有标注了@Component的类进行注入。

这里的通过构造方法进行注入就很好理解了,我们在装配MyBean这个零件的时候,突然发现他必须在AnotherBean的基础上才能安装到IOC里面,那么我们就在每次装配MyBean的时候自动装配:wrench:一个AnotherBean进去。举个:chestnut:吧:

还是以汽车为例,我们在踩油门出发之前,是不是必须发车??这里的AutoWired的内容就像发车,你不发车,这个油门你踩断都没有用,他都不会走。

通过set方法注入Bean

我们可以在一个属性的set方法中去将Bean实现注入,看代码吧


  • MyBean类
	@Component
	public class MyBeanSet {

    	private AnotherBean anotherBeanSet;

    	@Autowired
    	public void setAnotherBeanSet(AnotherBean anotherBeanSet) {
        	this.anotherBeanSet = anotherBeanSet;
    	}

    	@Override
    	public String toString() {
        	return "MyBeanSet{" +
            	"anotherBeanSet=" + anotherBeanSet +
            	'}';
    	}
	}
复制代码
  • Configuration类 和 Test类

同上一个,就不贴了


这里我们发现在setter方法上我们有一个@AutoWired,与上面不同的是,我们不会在实例化该类时就自动装配:wrench:这个对象,而是在显式调用setter的时候去装配。

通过属性去注入Bean

我们前面两种注入的方式诸如时间不同,并且代码较多,若是通过属性,即就是

	@Component
	public class MyBeanProperty {

    	@Autowired
    	private AnotherBean anotherBeanProperty;

    	@Override
    	public String toString() {
        	return "MyBeanProperty{" +
            	"anotherBeanProperty=" + anotherBeanProperty +
            	'}';
    	}
	}
复制代码

这里我们可以看到我们这个类中需要使用AnotherBean这个实例对象,我们可以通过@AutoWired去自动装配它。

对于有些小伙伴问私有属性,Spring怎么去加载它到IOC的?推荐去看看反射

通过List注入Bean

  • MyBeanList类
	@Component
	public class MyBeanList {

    	private List<String> stringList;

    	@Autowired
    	public void setStringList(List<String> stringList) {
        	this.stringList = stringList;
    	}

    	public List<String> getStringList() {
        	return stringList;
    	}
	}
复制代码
  • MyConfiguration类
	@Configuration
	@ComponentScan("annoBean.annotationbean")
	public class MyConfiguration {

	    @Bean
	    public List<String> stringList(){
	       List<String> stringList = new ArrayList<String>();
 	       stringList.add("List-1");
 	       stringList.add("List-2");
 	       return stringList;
	    }
	}
复制代码

这里我们将MyBeanList进行了注入,对List中的元素会逐一注入。下面介绍另一种方式注入List

  • MyConfiguration类
	@Bean
    //通过该注解设定Bean注入的优先级,不一定连续数字
    @Order(34)
    public String string1(){
        return "String-1";
    }

    @Bean
    @Order(14)
    public String string2(){
        return "String-2";
    }
复制代码

注入与List中泛型一样的类型,会自动去匹配类型,及时这里没有任何List的感觉,只是String的类型,但他会去通过List的Bean的方式去注入。

第二种方式的优先级高于第一种,当两个都存在的时候,若要强制去使用第一种方式,则要去指定Bean的id即可

通过Map去注入Bean

	@Component
	public class MyBeanMap {

    	private Map<String,Integer> integerMap;

    	public Map<String, Integer> getIntegerMap() {
    	    return integerMap;
    	}

    	@Autowired
    	public void setIntegerMap(Map<String, Integer> integerMap) {
    	    this.integerMap = integerMap;
    	}
	}
复制代码
	@Bean
    public Map<String,Integer> integerMap(){
        Map<String,Integer> integerMap = new HashMap<String, Integer>();
        integerMap.put("map-1",1);
        integerMap.put("map-2",2);
        return integerMap;
    }

    @Bean
    public Integer integer1(){
        return 1;
    }

    @Bean
    public Integer integer2(){
        return 2;
    }
复制代码

同样这里也具有两种方式去注入Map类型Bean,且第二种的优先值高于第一种

以上就是Bean通过注解注入的几种方式,大家可以对比着xml注入的方式去看。

转载于:https://juejin.im/post/5ca81a536fb9a05e6538aa39

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<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配置 | 遗留系统维护 | 集中管理 | | 工厂方法 | 复杂对象创建 | 创建逻辑封装 | ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值