Spring 装配Bean

一、Spring 装配Bean

1.1 Spring配置的可选方案

Spring提供了三种主要的装配机制:

  • 在XML中进行显式配置。
  • 在Java中进行显式配置。
  • 隐式的bean发现机制和自动装配。

在很多场景下,选择哪种方案很大程度上就是个人喜好的问题,你尽可以选择自己最喜欢的方式。

1.2 自动化装配bean

Spring从两个角度来实现自动化装配:

  • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
  • 自动装配(autowiring):Spring自动满足bean之间的依赖。

1)创建可被发现的bean

@Component 注解表明一个类会作为组件类,并告知Spring要为这个类创建bean

package mine;

public interface Fruit {

    String getName();

    String color();
}
import org.springframework.stereotype.Component;

@Component
public class Apple implements Fruit{

    @Override
    public String getName() {
        return "Apple";
    }

    @Override
    public String color() {
        return "Red";
    }
}

2)启用组件扫描(二选一)

使用基于Java的spring配置

@Configuration用于定义配置类, @ComponentScan 默认扫描该类所在的包下所有的配置类

package mine;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class MyApplicationContext {
}

通过XML启动组件扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/util
         http://www.springframework.org/schema/util/spring-util.xsd
         http://www.springframework.org/schema/data/jpa
         http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- 自动扫描 -->
    <context:component-scan base-package="mine" />
</beans>

3)为组件扫描的bean命名

@Component默认是将类名的第一个字母变为小写,也可以通过一下方式自定义一个名称

@Component("myApple")
public class Apple implements Fruit{
}

还可以使用Java依赖注入规范中的@Named注解来为bean设置ID,首先需要引入如下maven配置

<dependency>
  <groupId>javax.inject</groupId>
  <artifactId>javax.inject</artifactId>
  <version>1</version>
</dependency>
import javax.inject.Named;
@Named
public class Apple implements Fruit{
}

4) 设置组件扫描的基础包

@ComponentScan默认情况只扫描配置类所在的包,你可以通过指定包名来设置你要扫描的包

@Configuration
// 方法一
@ComponentScan(basePackages = {"package1","package2"})
public class MyApplicationContext {
}
@Configuration
// 方法二,这些类所在的包将会作为组件扫描的基础包。
@ComponentScan(basePackageClasses = {Apple.class, Fruit.class})
public class MyApplicationContext {
}

5)通过为bean添加注解实现自动装配

自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。为了声明要进行自动装配,我们可以借助Spring的@Autowired注解。

@Autowired
public static Apple apple;

@Autowired注解可以用在类的任何方法上,不管是构造器、Setter方法还是其他的方法,Spring都会尝试满足方法
参数上所声明的依赖。

如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,你可以将@Autowired的
required属性设置为false:

@Autowired(required = false)

1.3 通过Java代码装配bean

尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化配置是更为推荐的方式,但有时候自动化配置的方案行不通,因此需要明确配置Spring。比如说,你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component和@Autowired注解的,因此就不能使用自动化装配的方案了。

1)创建配置类

import org.springframework.context.annotation.Configuration;
@Configuration
public class MyApplicationContext {
}

2)声明简单的bean

@Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。默认情况下,bean的ID与带有@Bean注解的方法名是一样的,可以通过name属性设置一个不同的名称。,带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例,默认情况下,Spring中的bean都是单例的。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackageClasses = {Apple.class, Fruit.class})
public class MyApplicationContext {
	
	// 声明一个简单的bean
    @Bean
    public Apple apple(){
        return new Apple();
    }
    // 为bean显示声明一个名称
    @Bean(name = "myApple")
    public Apple getApple(){
        return new Apple();
    }
}

1.4 通过XML装配bean

1)创建XML配置文件:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/util
         http://www.springframework.org/schema/util/spring-util.xsd
         http://www.springframework.org/schema/data/jpa
         http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- 自动扫描 -->
    <context:component-scan base-package="mine" />
</beans>

2)声明一个简单的<bean>

class的值为类的全限定名,因为没有明确给定ID,所以这个bean将会根据全限定类名来进行命名。在本例中,bean的ID将会是“mine.Apple#0”。其中,“#0”是一个计数的形式,用来区分相同类型的其他bean。如果你声明了另外一个Apple,并且没有明确进行标识,那么它自动得到的ID将会是“mine.Apple#1”。

<bean class="mine.Apple"/>

手动指定一个bean名称

<bean id="myApple" class="mine.Apple" />

3)借助构造器注入初始化bean

在Spring XML配置中,只有一种声明bean的方式:使用<bean>元素并指定class属性。Spring会从这里获取必要的信息来创建bean。
但是,在XML中声明DI时,会有多种可选的配置方案和风格。具体到构造器注入,有两种基本的配置方案可供选择:

  • <constructor-arg>元素
  • 使用Spring 3.0所引入的c-命名空间

使用<constructor-arg>元素会告知Spring要将一个ID为beanID的bean引用传递到mine.Apple的构造器中。

<bean class="mine.Apple">
   <constructor-arg ref="beanID" />
</bean>

使用Spring 3.0所引入的c-命名空间。
在这里插入图片描述

<bean class="mine.Apple" c:name-ref="myApple"/>

在这里插入图片描述

4) 将字面量注入到构造器中

假设有如下示列

public class Apple implements Fruit{

    private String name;

    private String color;

    public Apple(){

    }

    public Apple(String name, String color) {
        this.name = name;
        this.color = color;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String color() {
        return color;
    }
}

配置如下(二选一)

<bean class="mine.Apple">
    <constructor-arg value="Apple"/>
    <constructor-arg value="Red"/>
</bean>
<bean class="mine.Apple" c:name="Apple" c:color="Red"/>

5)装配集合

加入有如下示列代码

public class Apple implements Fruit{

    private String name;

    private String color;

    private List<String> type;

    public Apple(){

    }

    public Apple(String name, String color, List<String> type) {
        this.name = name;
        this.color = color;
        this.type = type;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String color() {
        return color;
    }
}

传入null

<bean class="mine.Apple">
    <constructor-arg value="Apple"/>
    <constructor-arg value="Red"/>
    <constructor-arg><null/></constructor-arg>
</bean>

为集合传值,其中如果集合是Object类型的话,我们也可以使用<ref bean/>替换<value>

<bean class="mine.Apple">
   <constructor-arg value="Apple"/>
   <constructor-arg value="Red"/>
   <constructor-arg>
       <list>
           <value>type one</value>
           <value>type two</value>
       </list>
   </constructor-arg>
</bean>

6)设置属性

使用 <property>元素设置

<bean class="mine.Apple">
    <property name="name" value="Apple" />
    <property name="color" value="Apple" />
    <property name="type">
        <list>
            <value>type one</value>
            <value>type two</value>
        </list>
    </property>
</bean>

使用p命名空间

在这里插入图片描述

<util:list id="AppleType">
    <value>apple one</value>
    <value>apple two</value>
</util:list>

<bean class="mine.Apple" p:color="" p:name="" p:type-ref="AppleType" />

7) Spring util-命名空间中的元素

元素描述
util:constant引用某个类型的public static域,并将其暴露为bean
util:list创建一个java.util.List类型的bean,其中包含值或引用
util:map创建一个java.util.Map类型的bean,其中包含值或引用
util:properties创建一个java.util.Properties类型的bean
util:property-path引用一个bean的属性(或内嵌属性),并将其暴露为bean
util:set创建一个java.util.Set类型的bean,其中包含值或引用

1.5 导入和混合配置

1)使用@Import导入其他配置类

@Configuration
@Import(Apple.class)
@ComponentScan(basePackageClasses = {Apple.class, Fruit.class})
public class MyApplicationContext {
}

2)在JavaConfig中引用XML配置

要在Java配置类中使用XML配置需要用到@ImportResource注解

@Configuration
@Import(Apple.class)
@ImportResource("classpath:xml_name.xml")
@ComponentScan(basePackageClasses = {Apple.class, Fruit.class})
public class MyApplicationContext {
}

3)在XML中引入其他XML文件

<import resource="applicationContext.xml" />

4)在XML配置中引用JavaConfig

只需要为Java创建一个bean即可

<bean class="mine.MyApplicationContext"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

书香水墨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值