Spring-基于Java类的配置

举报
小工匠 发表于 2021/09/10 01:54:15 2021/09/10
【摘要】 概述使用Java类提供Bean定义信息 实例分析 使用基于Java类的配置信息启动Spring容器 直接通过Configuration启动Spring容器 通过A...

概述

JavaConfig是Spring的一个子项目,它旨在通过Java类的方式提供Bean的定义信息,在Spring4.0的版本,JavaConfig正式成为Spring4.0的核心功能。


使用Java类提供Bean定义信息

普通的POJO只要标注了@Configuration注解,就可以为Spring容器提供Bean定义的信息,每个标注了@Bean的类方法都相当于提供一个Bean的定义信息。


实例

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

这里写图片描述

POJO

package com.xgj.ioc.javaConfig;

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

// 将一个POJO标注为定义Bean的配置类
@Configuration
public class Teacher {

    /**
     * 
     * 
     * @Title: studentOne
     * 
     * @Description: 定义了一个Bean,并提供了Bean的实例化逻辑
     * 
     * @return
     * 
     * @return: StudentOne
     */
    @Bean
    public StudentOne studentOne() {
        return new StudentOne();
    }

    /**
     * 
     * 
     * @Title: studentTwo
     * 
     * @Description: 定义了一个Bean,并提供了Bean的实例化逻辑
     * 
     * @return
     * 
     * @return: StudentTwo
     */
    @Bean
    public StudentTwo studentTwo() {
        return new StudentTwo();
    }

    public void arrangeStudent() {
        studentOne().doCleanWork();
        studentTwo().doHomeWork();
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
package com.xgj.ioc.javaConfig;

public class StudentOne {

    public void doCleanWork() {
        System.out.println("StudentOne will do CleanWork");
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
package com.xgj.ioc.javaConfig;

public class StudentTwo {
    public void doHomeWork() {
        System.out.println("StudentTwo will do HomeWork");
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

测试类

package com.xgj.ioc.javaConfig;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class JavaConfigTest {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(
                Teacher.class);
        ctx.getBean("teacher", Teacher.class).arrangeStudent();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

运行结果

这里写图片描述


分析

Teacher类的定义出标注了@Configuration注解,说明这个类可以用于为Spring提供Bean的定义信息。
该类的方法可以标注@Bean注解,Bean的类型由方法返回值的类型决定,名称默认和方法名同名,当然也可以通过入参显示指定Bean名称,比如@Bean(name=”coolStudent”).
@Bean所标注的方法体提供了Bean的实例化逻辑。

studentOne()和studentTwo()方法分别定义了一个StudentOne 和 StudentTwo类型的Bean, 他们的Bean名称分别为 studentOne 和 studentTwo。

在arrangeStudent()方法中 注入了上面实例化的两个Bean。

以上配置和下面的xml是等效的

<bean id="studentOne" class="com.xgj.ioc.javaConfig.StudentOne"/>
<bean id="studentTwo" class="com.xgj.ioc.javaConfig.StudentTwo"/>
<bean id="teacher" class="com.xgj.ioc.javaConfig.Teacher"
p:sutdentOne-ref="studentOne" p:studentTwo-ref="studentTwo"/>
  
 
  • 1
  • 2
  • 3
  • 4

基于Java类的配置方式和基于XML或者基于注解的配置方式相比,前者通过代码编程的方式可以更加灵活的实现Bean的实例化及Bean之间的装配,后两者都是通过配置声明的方式,在灵活性上要稍逊一些,但在配置上要更简单一些。


使用基于Java类的配置信息启动Spring容器

1.直接通过@Configuration启动Spring容器

Spring提供了AnnotationConfigApplicationContext类,它能够直接通过标注@Configuration的Java类启动Spring容器。

通过AnnotationConfigApplicationContext的构造函数加载配置类

比如我们上面的那个例子的测试类

package com.xgj.ioc.javaConfig;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class JavaConfigTest {

    public static void main(String[] args) {
        // (1)通过构造函数加载配置类       
        ApplicationContext ctx = new AnnotationConfigApplicationContext(
                Teacher.class);
        ctx.getBean("teacher", Teacher.class).arrangeStudent();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在(1)处,通过AnnotationConfigApplicationContext类的构造函数直接传入标注了@Configuration的JAVA类,这届用该类中提供的Bean定义信息启动Spring容器。


通过编码的方式加载多个@Configuration配置类,然后通过刷新容器应用这些配置类

package com.xgj.ioc.javaConfig;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class JavaConfigTest {

    public static void main(String[] args) {
        // 通过构造函数加载配置类
        // ApplicationContext ctx = new AnnotationConfigApplicationContext(
        // Teacher.class);

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        // 注册@Configuration的配置类,可注册多个
        ctx.register(Teacher.class);
        // 刷新容器以应用这些注册的配置类
        ctx.refresh();

        Teacher teacher = ctx.getBean("teacher", Teacher.class);
        teacher.arrangeStudent();

    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

通过@Import将多个配置类组装到一个配置类中,然后仅需注册这个组装好的配置类 ,启动容器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(DaoConfig.class)
public class ServiceConfig {

    @Autowired
    private DaoConfig daoConfig;

    @Bean
    public LogonService logonService(){
        LogonService logonService = new LogonService();
        System.out.println(daoConfig.logDao() == daoConfig.logDao());
        logonService.setLogDao(daoConfig.logDao());
        logonService.setUserDao(daoConfig.userDao());
        return logonService;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

AnnotationConfigApplicationContext的主要方法
这里写图片描述


2.通过XML配置文件引用@Configuration配置

标注了@Configuration的配置类和标注了@Component的类一样也是一个Bean, 同样的 它也可以被Spring的<context:component-scan>扫描到。 因此如果希望将配置类组装到XML的配置文件中,通过XML的配置文件启动Spring,这仅需要在XML子中通过<context:component-scan>扫描到相应的配置类即可。

我们改造下上面的测试类

这里写图片描述

增加配置文件:

<?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:context="http://www.springframework.org/schema/context"

    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd

            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">


    <!-- (1)声明Context命名空间以及Schema文件 (2)扫描类包以及应用注解定义的bean  resource-pattern 看需求,可配置可不配置 -->
    <context:component-scan base-package="com.xgj.ioc.javaConfig"
        resource-pattern="Teacher.class" />

</beans>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
package com.xgj.ioc.javaConfig;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class JavaConfigTest {

    public static void main(String[] args) {

    ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/xgj/ioc/javaConfig/beans.xml");

        Teacher teacher = ctx.getBean("teacher", Teacher.class);
        teacher.arrangeStudent();

    }
}
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

同样也可以正确的加载并实例化Bean

2017-07-31 22:03:02,093  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@d167d36: startup date [Mon Jul 31 22:03:02 BOT 2017]; root of context hierarchy
2017-07-31 22:03:02,176  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/ioc/javaConfig/beans.xml]
StudentOne will do CleanWork
StudentTwo will do HomeWork
  
 
  • 1
  • 2
  • 3
  • 4

3.通过@Configuration配置类引用XML配置信息

假设bean中有两个Bean ,如下

<bean id="userDao" class="com.xgj.ioc.javaConfig.UserDao"/>
<bean id="logDao" class="com.xgj.ioc.javaConfig.LogDao"/>
  
 
  • 1
  • 2

在@Configuration配置类中可以直接通过@ImportResource引入XML的配置那文件,这样就就可以直接通过@Autowired引用xml配置文件中定义的Bean。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ImportResource("classpath:com/xgj/ioc/javaConfig/beans.xml")
public class LogonAppConfig {

    @Bean
    @Autowired
    public LogonService logonService(UserDao userDao,LogDao logDao){
        LogonService logonService = new LogonService();
        logonService.setUserDao(userDao);
        logonService.setLogDao(logDao);
        return logonService;        
    }
}
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

通过@ImportResource引入XML配置文件
通过@Bean定义一个LogonService 的bean
通过@Autowired自动注入userDao和logDao ,这两个Bean是在XML配置文件中定义的。

需要说明的是,@ImportResource引入XML配置文件,不是@Autowired处可成功注入到对应Bean的前提条件。 只要不同形式的Bean定义信息能够加载到Spring容器中,Spring就可以智能的完成Bean之间的装配。

文章来源: artisan.blog.csdn.net,作者:小小工匠,版权归原作者所有,如需转载,请联系作者。

原文链接:artisan.blog.csdn.net/article/details/76362207

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。