IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring容器-Java代码配置方式 -> 正文阅读

[Java知识库]Spring容器-Java代码配置方式

JavaConfig

我们通常使用 Spring 都会使用 XML 配置,随着功能以及业务逻辑的日益复杂,应用伴随着大量的 XML 配置文件以及复杂的 bean 依赖关系,使用起来很不方便。

一个很大的项目,把一个大的项目拆分多个子项目(10 个 20 个 左右)(分布式项目) , 若现在还用 xml 配置, 想吐了

在 Spring 3.0 开始,Spring 官方就已经开始推荐使用 Java 配置来代替传统的 XML 配置了,它允许开发者将 bean 的定义和 Spring 的配置编写到到 Java 类中,不过似乎在国内并未推广盛行。当 Spring Boot 来临,人们才慢慢认识到 Java 配置的优雅,但是,也仍然允许使用经典的 XML 方式来定义 bean 和 配置 Spring。其有以下优势:

  • 面向对象的配置。由于配置被定义为 JavaConfig 中的类,因此用户可以充分使用 Java 中的面向对象功能。一个配置类可以继承另一个,重写它的 @Bean 方法等。
  • 减少或者消除 XML 配置。提供了一种纯 Java 的方式来配置与 XML 配置概念相似的 Spring 容器。
  • 类型安全和重构友好。提供了一种类型安全的方法了来配置 Spring 容器,由于 Java 5 对泛型的支持,现在可以按类型而不是名称检索 bean,不需要任何的强制转换或者基于字符串的查找。

xml配置与java配置的区别

搭建一个基于 Maven 构建的项目 java-config-demo,添加如下依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.8.RELEASE</version>
</dependency>

XML 方式配置 IoC

在 XML 配置文件中去配置这些 Bean 交给 Spring 管理。

<!-- applicationContext.xml -->
<bean id="someBean" class="cn.xxxx.bean.SomeBean"/>

启动 Spring 读取该 XML 文件创建容器对象,从容器中获取 SomeBean 对象。

public class IoCTest {
    @Test
    public void testXmlConfig() {
        ApplicationContext ctx = new ClassPathXmlApplicationContexnt("classpath:applicationContext.xml");//根据配置文件启动
        SomeBean someBean = ctx.getBean(SomeBean.class);
        System.out.println(someBean);
    }
}

JavaConfig 方式配置 IoC

JavaConfig 方式中使用注解彻底的替代 XML 文件,那么到底要怎么告诉 Spring 容器,bean 没有定义在 XML 文件中,而是定义在一个 Java 配置类中。

  • @Configuration:在类上贴该注解表示该类是 Spring 的配置类,具有applicationContext.xml 文件的作用。
  • @Bean:在 Spring 的配置类的方法上贴该注解后,该方法返回的对象会交给 Spring 容器管理,替代 applicationContext.xml 中的 bean 标签。
  • @ComponentScan:在 Spring 配置类上贴该注解表示开启组件扫描器,默认扫描当前配置类所在的包,也可以自己指定,替代 XML 配置中的 <context:component-scan /> 标签。
  • AnnotationConfigApplicationContext:该类是 ApplicationContext 接口的实现类,该对象是基于 JavaConfig 的方式来运作的 Spring 容器。

定义一个配置类
替代之前的 XML 文件,类中定义方法,返回 bean 对象交给 Spring 管理。

/**
* @Configuration
* 贴有该注解的类表示 Spring 的配置类
* 用于替代传统的 applicationContext.xml
*/
@Configuration
public class JavaConfig { 
    
    /**
    * @Bean
    * 该注解贴在配置类的方法上,该方法会被 Spring 容器自动调用
    * 并且返回的对象交给 Spring 管理
    * 相当于 <bean id="someBean" class="cn.xxx.bean.SomeBean"/>
    */
    @Bean
    public SomeBean someBean() {
        return new SomeBean();
    }
}

加载配置类,启动 AnnotationConfigApplicationContext 容器对象,测试效果。

public class IoCTest {
    @Test
    public void testJavaConfig() {
        // 加载配置类,创建 Spring 容器
        ApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);//根据java配置类启动
        // 从容器中取出 SomeBean 对象
        SomeBean someBean = ctx.getBean(SomeBean.class);
        System.out.println(someBean);
    }
}

@Bean 注解中的属性
在 XML 配置 bean 的方式中,我们可以在 bean 标签中的 id,name,init-method,destroy-method,scope 等属性来完成对应的配置,在使用 JavaConfig 方式中我们也一样能通过相应的配置来完成同样的效果,这些效果大多封装到 @Bean 注解的属性中。@Bean 注解中的属性有以下:

  • name:对应 bean 标签中的 name 属性,用于给 bean 取别名;
  • initMethod:对应 bean 标签中的 init-method 属性,配置 bean 的初始化方法;
  • destroyMethod:对应 bean 标签中的 destroy-method 属性,配置 bean 的销毁方法。

注意:在配置类的方式中有许多的默认规定,比如:

  • bean 的 id 就是当前方法名
  • 配置多例则是在方法上添加 @Scope("prototype") 注解来实现,一般不用配,默认单例即可。

XML 方式配置 DI

<bean id="someBean" class="cn.xxx.bean.someBean">
    <property name="otherBean" ref="otherBean"/>
</bean>

<bean id="otherBean" class="cn.xx.bean.OtherBean"/>

JavaConfig 方式配置 DI

在配置类方式中我们有两种方式可以完成依赖注入,无论是哪种方式,前提都是要先把 bean 交给 Spring 管理,然后在把 bean 注入过去后再使用 setter 方法设置关系。通用步骤:先把两个 bean 交给 Spring 管理。

@Bean
public SomeBean someBean() {
    SomeBean someBean = new SomeBean();
    return someBean;
}
@Bean
public OtherBean otherBean() {
    return new OtherBean();
}

通过方法形参注入

把需要注入的 bean 对象作为参数传入到另一个 bean 的方法声明中,形参名称最好跟 bean 的 id 一致。在容器里面有的 bean,都可以用这种方式注入。

// 在声明 SomeBean 的方法形参中直接注入 OtherBean 对象
@Bean
public SomeBean someBean(OtherBean otherBean) {
    SomeBean someBean = new SomeBean();
    someBean.setOtherBean(otherBean);
    return someBean;
}

调用方法注入

// 调用上面已经声明的 otherBean 方法 
@Bean
public SomeBean someBean() {
    SomeBean someBean = new SomeBean();
    someBean.setOtherBean(otherBean());
    return someBean;
}

原理:Spring 容器在调用实例方法时,根据方法返回对象类型,判断容器中是否已经存在该类型的实例对象,如果不存在则执行实例方法,将返回对象实例交给容器管理,如果该实例已经存在了,直接从容器中拿已经存在实例对象方法,不执行实例方法。

使用 IoC DI 注解简化配置

以上案例中,在配置类内部去定义方法返回 bean 对象交给 Spring 管理的方式存在一个问题,就是如果需要创建的 bean 很多的话,那么就需要定义很多的方法,会导致配置类比较累赘,使用起来不方便。以前可以通过注解简化 XML 配置,现在同样也可以通过注解简化 JavaConfig,这里需要使用到 @ComponentScan 注解,等价于之前 XML 配置的 <context:component-scan base-package="贴了 IoC DI 注解的类所在的包"/>

@Configuration // 表示该类是 Spring 的配置类
@ComponentScan // 开启组件扫描器,默认扫描当前类所在的包,及其子包
public class JavaConfig { }

若需要扫描的包不是配置类所在的包时,我们可以通过注解中的 value 属性来修改扫描的包。

注意:组件扫描的方式只能扫描我们自己写的组件,若某个 bean 不是我们写的(这个类的设计者不一定使用了spring ioc 注解将这个类交给spring容器管理),则还是要通过在配置类中定义方法来处理,两者是可以同时存在的。

Spring Test 方式加载配置类

首先在 pom.xml 添加如下依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.8.RELEASE</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.6.3</version>
    <scope>test</scope>
</dependency>

JUnit4 的方式 基于 XML

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:XML文件路径")
public class IoCTest { 
    @Autowired
    private SomeBean someBean;

    @Test
    public void test() {
        System.out.println(someBean);
    }
}

JUnit4 的方式 基于配置类

@ContextConfiguration 注解不仅支持 XML 方式启动 Spring 测试,也支持配置类的方式,配置 classes 属性来指定哪些类是配置类即可。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={配置类1.class, 配置类2.class, ...})
public class IoCTest {
    @Autowired
    private SomeBean someBean;

    @Test
    public void test() {
        System.out.println(someBean);
    }
}

JUnit5 的方式

注意测试类和测试方法都不用 public 修饰,测试类只需要贴 @SpringJUnitConfig 指定加载的配置即可。

@SpringJUnitConfig(配置类.class)
class IoCTest {
    @Autowired
    private SomeBean someBean;

    @Test
    void test() {
        System.out.println(someBean);
    }
}

配置类的导入

在 Spring 项目中一般都会有多个 Spring 的配置文件,分别配置不同的组件,最后关联到主配置文件中,该功能也是同样可以在配置类的方式中使用的。

XML 方式

<!-- 例如 mvc.xml 中导入 applicationContext.xml -->
<import resource="classpath:applicationContext.xml"/>

配置类方式

需要使用 @Import 来完成,指定导入的配置类。

// 主配置类
@Configuration
@Import(OtherJavaConfig.class) // 在主配置类中关联次配置类
public class JavaConfig { ... }

// 次配置类
@Configuration
public class OtherJavaConfig { ... }

// 测试
@SpringJUnitConfig(classes = JavaConfig.class) // 加载主配置类
public class IoCTest { ... }

配置类导入 XML 配置

需要使用 @ImportResource 来完成,指定导入 XML 配置文件的路径。

// 主配置类
@Configuration
@ImportResource("classpath:XML文件路径") // 在主配置类中关联 XML 配置
public class JavaConfig { ... }

// 测试
@SpringJUnitConfig(classes = JavaConfig.class) // 加载主配置类
public class IoCTest { ... }
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:40:47  更:2022-10-31 11:46:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 4:14:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码