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之间的装配。

相关文章
|
5月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
5月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
5月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
228 4
|
5月前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
296 5
|
5月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
281 1
|
5月前
|
Java Go 开发工具
【Java】(8)正则表达式的使用与常用类分享
正则表达式定义了字符串的模式。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
402 1
|
5月前
|
存储 Java 程序员
【Java】(6)全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
272 1
|
5月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
300 1
Java相关配置
Java相关配置
1394 0
|
6月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案

热门文章

最新文章