Spring-基于Java类的配置

简介: Spring-基于Java类的配置

概述


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


使用Java类提供Bean定义信息


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


实例


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


20170730111023082.jpg


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();
    }
}


package com.xgj.ioc.javaConfig;
public class StudentOne {
    public void doCleanWork() {
        System.out.println("StudentOne will do CleanWork");
    }
}
package com.xgj.ioc.javaConfig;
public class StudentTwo {
    public void doHomeWork() {
        System.out.println("StudentTwo will do HomeWork");
    }
}

测试类

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();
    }
}


运行结果


20170730111151797.jpg


分析


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"/>

基于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)处,通过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();
    }
}


通过@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;
    }
}

AnnotationConfigApplicationContext的主要方法


20170801092141130.jpg


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


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


我们改造下上面的测试类


20170801100454888.jpg


增加配置文件:

<?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>


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();
    }
}

同样也可以正确的加载并实例化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


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

假设bean中有两个Bean ,如下


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

在@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;        
    }
}

通过@ImportResource引入XML配置文件

通过@Bean定义一个LogonService 的bean

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


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

相关文章
|
4天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
28 3
|
1天前
|
安全 Java 程序员
|
1天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
1天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
|
2天前
|
Java
Java Class类
Java Class类
8 0
|
2天前
|
Java
Java配置环境
Java配置环境
9 0
Java配置环境
|
6天前
|
存储 安全 Java
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
16 0
|
6天前
|
安全 Java 数据库
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(上)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)
28 0
|
7天前
|
安全 Java Spring
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
19 0
|
7天前
|
安全 Java 应用服务中间件
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
24 0
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置