Spring Bean配置

简介: Spring Bean管理Spring的核心在于Ioc,我们上一篇已经提到了Ioc的概念,把对象的控制权较给容器来管理。在Spring中,凡是被Spring创建和管理的对象都叫做Bean。

Spring Bean管理

Spring的核心在于Ioc,我们上一篇已经提到了Ioc的概念,把对象的控制权较给容器来管理。在Spring中,凡是被Spring创建和管理的对象都叫做Bean。

img_52cca314f7a7c4d95cbf593c27d5346e.png
Bean

Spring管理的Bean,一般是由你提供的配置来创建,如Java配置,注解配置,XML配置。在容器内部,这些Bean表现为BeanDefinition对象。

Bean的配置

基于XML的配置

在xml中,我们可以更了解Bean的配置,一个配置案例如下:


img_8c8a5eb88fe11371a004577104879939.png
常见xml配置

分别解说各个参数的作用:

  • class: 要实例化的类。所谓的bean在内存中就是实例化后的对象。class指的是要实例化那个类。
  • name: Bean的名称,便于记忆
  • scope: 下面会提到
  • constructor arguments: 构造器参数
  • properties 属性
  • autowiring模式,Bean依赖其它Bean时候的模式
  • lazy-initialization 懒加载模式
  • initialization 初始化方法
  • destruction 销毁方法

直接拿一个XML注解的案例来说明:
还记得上一篇文章需要的几个类吗,这里我们再用一次。

  1. 准备好Java对象
public interface HelloWord {
    void sayHello();
}

public class HelloWordImpl1 implements HelloWord {
    @Override
    public void sayHello() {
        System.out.println("hello1");
    }
}

public class HelloWordImpl2 implements HelloWord {
    @Override
    public void sayHello() {
        System.out.println("hello2");
    }
}
  1. 根据不同的XML配置,获得不同的结果

2.1 scope的作用

scope为prototype时,每次从容器中获取bean,相应的对象都会重新实例化一次,也就是每次拿到的都是新创建的对象。
scope为singleton的时候,bean一直在容器中存在,直接容器销毁之前销毁,每次获取bean,获取到的是同一个bean


//准备好App文件

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        HelloWord helloWord = applicationContext.getBean(HelloWord.class);
        HelloWord helloWord2 = applicationContext.getBean(HelloWord.class);
        helloWord.sayHello();
        System.out.println(helloWord2);
    }
}

<bean id="helloworld" class="me.aihe.HelloWordImpl2" scope="prototype"/>
//运行结果
me.aihe.HelloWordImpl2@6a2bcfcb
me.aihe.HelloWordImpl2@4de8b406

<bean id="helloworld" class="me.aihe.HelloWordImpl2" scope="singleton"/>
//运行结果
me.aihe.HelloWordImpl2@6d8a00e3
me.aihe.HelloWordImpl2@6d8a00e3

Spring默认bean的scope为singleton。

2.2 construct-arg参数
这个参数是构造bean对象的时候,提供构造参数
[图片上传失败...(image-d2cf54-1526781442058)]

  • ref指的是,当构造某个bean的时候,这个bean依赖其它的bean,使用ref来指向依赖的bean
  • type: 构造器参数中,精确的类型是什么,String或其它等等
  • index: 构造器参数具体的索引
//还是给一个简单运行的案例
//改造HelloWordImp2
public class HelloWordImpl2 implements HelloWord {

    String str;
    
    public HelloWordImpl2(String str) {
        this.str = str;
        System.out.println("实例化str:" + str);
    }

    public void sayHello() {
        System.out.println("hello2");
    }
}
//XML配置
   <bean id="helloworld" class="me.aihe.HelloWordImpl2">
        <constructor-arg type="java.lang.String" value="你好" />
    </bean>
     <bean id="helloworld" class="me.aihe.HelloWordImpl2">
        <constructor-arg index="0" value="你好" />
    </bean>
    <bean id="helloworld" class="me.aihe.HelloWordImpl2">
        <constructor-arg name="str" value="你好" />
    </bean>
    
// 以上三个bean只需要其中一个就好了,这里演示的是三个的运行结果都是一样的
//运行结果都是
实例化str:你好
me.aihe.HelloWordImpl2@d8355a8
me.aihe.HelloWordImpl2@d8355a8

2.3 property属性
property主要配置Java对象中有setter和getter方法的属性。

2.4 autowiring模式,保持默认就好,bean解析的方式,byType,byName

2.5 lazy-init赖加载模式
当设置为true的时候,只有在我们需要这个对象的时候,才会被实例化。

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        System.out.println("初始化applicationContext完成");
        HelloWord helloWord = applicationContext.getBean(HelloWord.class);
        System.out.println(helloWord);
    }
}


public class HelloWordImpl2 implements HelloWord {
    
    public HelloWordImpl2() {
        System.out.println("实例化中");
    }
    public void sayHello() {
        System.out.println("hello2");
    }
}

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="true" />
// 运行结果
初始化applicationContext完成
实例化中
me.aihe.HelloWordImpl2@573f2bb1

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" />
//运行结果
实例化中
初始化applicationContext完成
me.aihe.HelloWordImpl2@6d8a00e3

可以看到,使用lay-init为true之后,在应用初始化完成后,只有再调用的时候才会实例化具体的bean。而设置为false则在初始化applicationContext的时候就实例化了。

2.6 init-method
在实例化该对象的后,调用此方法

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" init-method="sayHello"/>

//运行结果
实例化中
hello2
初始化applicationContext完成
me.aihe.HelloWordImpl2@6d8a00e3

2.7 destroy-method
容器销毁该bean的时候,调用此方法

public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        System.out.println("初始化applicationContext完成");
        HelloWord helloWord = applicationContext.getBean(HelloWord.class);
        System.out.println(helloWord);
        ((ClassPathXmlApplicationContext) applicationContext).destroy();
    }
}

public class HelloWordImpl2 implements HelloWord {


    public HelloWordImpl2() {
        System.out.println("实例化中");
    }
    public void sayHello() {
        System.out.println("hello2");
    }

    public void sayGoodBye(){
        System.out.println("拜拜");
    }
}

<bean id="helloworld" class="me.aihe.HelloWordImpl2" lazy-init="false" init-method="sayHello" destroy-method="sayGoodBye"/>

// 运行结果
实例化中
hello2
初始化applicationContext完成
me.aihe.HelloWordImpl2@6d8a00e3
拜拜

基于注解与基于Java的配置

了解了XML配置之后,注解的配置更加简单,关键的几个注解如下

  • @Bean, 可以指定name,init-method,destroy-method,autowire

  • @Lazy 指定bean是否要懒加载

  • @Scope 指定scope

  • @Primary 当有多个bean类型相同的时候,指定优先使用带有@primary的bean,有多个@primary标记类型相同的bean的时候,会报错

  • @Component,@controller,@Service,@Reposotory 标记某个对象为bean

Bean的扫描

在XML配置中

// 开启注解配置
<context:annotation-config />
// 扫描bean所在的包
<context:component-scan base-package="me.aihe" />

Java配置

@ComponentScan(value = "me.aihe")

小结

这篇文章主要讲了Bean的常见配置,Bean的配置还有更深入的内容,等待我们去探索。

相关文章
|
11月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
11月前
|
Java 关系型数据库 MySQL
Spring Boot自动配置:魔法背后的秘密
Spring Boot 自动配置揭秘:只需简单配置即可启动项目,背后依赖“约定大于配置”与条件化装配。核心在于 `@EnableAutoConfiguration` 注解与 `@Conditional` 系列条件判断,通过 `spring.factories` 或 `AutoConfiguration.imports` 加载配置类,实现按需自动装配 Bean。
|
11月前
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
2989 0
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
1370 0
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
1401 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
安全 Java API
深入解析 Spring Security 配置中的 CSRF 启用与 requestMatchers 报错问题
本文深入解析了Spring Security配置中CSRF启用与`requestMatchers`报错的常见问题。针对CSRF,指出默认已启用,无需调用`enable()`,只需移除`disable()`即可恢复。对于`requestMatchers`多路径匹配报错,分析了Spring Security 6.x中方法签名的变化,并提供了三种解决方案:分次调用、自定义匹配器及降级使用`antMatchers()`。最后提醒开发者关注版本兼容性,确保升级平稳过渡。
1637 2
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
1074 26
|
10月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
1934 0
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
424 0