`

41. Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】

阅读更多

 

 à悟空学院:https://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/A6ZagYTi

Spring Cloud视频:http://t.cn/A6ZagxSR

SpringBoot Shiro视频:http://t.cn/A6Zag7IV

SpringBoot交流平台:https://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/A6Zad1OH

SpringSecurity5.0视频:http://t.cn/A6ZadMBe

Sharding-JDBC分库分表实战http://t.cn/A6ZarrqS

分布式事务解决方案「手写代码」:http://t.cn/A6ZaBnIr

 

  已经好久没有讲一些基础的知识了,这一小节来点简单的,这也是为下节的在Spring Boot中使用多数据源做准备。

Spring 3.0开始,增加了一种新的途径来配置Bean Definition,这就是通过Java Code配置Bean Definition

       XMLAnnotation两种配置方式不同点在于:

       前两种方式XMLAnnotation的配置方式为预定义方式,即开发人员通过XML文件或者Annotation预定义配置Bean的各种属性后,启动Spring容器,Spring容器会首先解析这些配置属性,生成对应的Bean Definition,装入到DefaultListtableBeanFactory对象的属性容器中,以此同时,Spring框架也会定义内部使用的Bean定义,如Bean名为:org.springframework.context.annotation.internalConfigurationAnnotationProcessor” ConfigurationClassPostProcessor 定义。而后此刻不会做任何Bean Definition的解析动作,Spring框架会根据前两种配置,过滤出BeanDefinitionRegistryPostProcessor 类型的Bean定义,并通过Spring框架生成对应的Bean对象(如 ConfigurationClassPostProcessor 实例)。。结合 Spring 上下文源码可知这个对象是一个 processor 类型工具类,Spring 容器会在实例化开发人员所定义的 Bean 前先调用该 processor postProcessBeanDefinitionRegistry() 方法。此处实现基于 Java Code 配置Bean Definition的处理。

 

       基于 Java Code 的配置方式,其执行原理不同于前两种。它是在 Spring 框架已经解析了基于 XML Annotation 配置后,通过加入 BeanDefinitionRegistryPostProcessor 类型的 processor 来处理配置信息,让开发人员通过 Java 编程方式定义一个 Java 对象。其优点在于可以将配置信息集中在一定数量的 Java 对象中,同时通过 Java 编程方式,比基于 Annotation 方式具有更高的灵活性。并且该配置方式给开发人员提供了一种非常好的范例来增加用户自定义的解析工具类。其主要缺点在于与 Java 代码结合紧密,配置信息的改变需要重新编译 Java 代码,另外这是一种新引入的解析方式,需要一定的学习成本。

 

提及一点的就是,Spring框架有3个主要的Hook类,分别是:

org.springframework.context.ApplicationContextAware 
它的setApplicationContext 方法将在Spring启动之前第一个被调用。我们用来同时启动Jdon框架。

org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor 
它的postProcessBeanDefinitionRegistry postProcessBeanFactory 方法是第二和第三被调用,它们在Bean初始化创建之前启动,如果Springbean需要的其他第三方中的组件,我们在这里将其注入给Spring

org.springframework.context.ApplicationListener 
用于在初始化完成后做一些事情,当Spring所有XML或元注解的Bean都启动被创建成功了,这时会调用它的唯一方法onApplicationEvent

 

下面我们来完成一个,自己通过java代码创建bean,并注册为Spring管理。 
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

本例中,我们创建一个接口,然后创建该接口的2个实现类,分别命名不同的名字,然后在需要注入的地方使用@Qualifier 指定注入对应的实例。

 

接口com.kfit.demo.Shanhy.java

package com.kfit.demo;

 

publicinterface Shanhy {

  

   publicvoid dispaly();

  

}

 

实现类com.kfit.demo.ShanhyA.java

package com.kfit.demo;

 

publicclass ShanhyA implements Shanhy{

 

   @Override

   publicvoid dispaly() {

      System.out.println("ShanhyA.dispaly()");

   }

}

 

 

实现类com.kfit.ShanhyB.java

package com.kfit.demo;

 

publicclass ShanhyB implements Shanhy {

 

   @Override

   publicvoid dispaly() {

      System.out.println("ShanhyB.dispaly()");

   }

 

}

 

 

定义接口BeanDefinitionRegistryPostProcessor的实现:

com.kfit.config.MyBeanDefinitionRegistryPostProcessor:

package com.kfit.config;

 

import org.springframework.beans.BeansException;

import org.springframework.beans.MutablePropertyValues;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;

import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;

import org.springframework.beans.factory.config.BeanDefinition;

import org.springframework.beans.factory.config.BeanDefinitionHolder;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

import org.springframework.beans.factory.support.BeanNameGenerator;

import org.springframework.context.annotation.AnnotationBeanNameGenerator;

import org.springframework.context.annotation.Configuration;

 

import com.kfit.demo.ShanhyA;

import com.kfit.demo.ShanhyB;

 

/**

 * 实现自己实例化bean并注册为Spring管理

 * @author Angel(QQ:412887952)

 * @version v.0.1

 */

@Configuration

publicclass MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

   

    //bean 的名称生成器.

     private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

 

   

    @Override

    publicvoid postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

       System.out.println("MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory()");

      

             

    }

 

    /**

     * 先执行:postProcessBeanDefinitionRegistry()方法,

     * 在执行:postProcessBeanFactory()方法。

     *

     */

    @Override

    publicvoid postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

    System.out.println("MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()");

      

       /*

        * 在这里可以注入bean.

        */

       registerBean(registry, "shanyA", ShanhyA.class);

       registerBean(registry, "shanyB", ShanhyB.class);

    }

   

    /**

     * 提供公共的注册方法。

     * @param beanDefinitionRegistry

     * @param name

     * @param beanClass

     */

    privatevoid registerBean(BeanDefinitionRegistry registry,String name,Class<?> beanClass){

       AnnotatedBeanDefinition annotatedBeanDefinition  = new AnnotatedGenericBeanDefinition(beanClass);

         //可以自动生成name

       String beanName = (name != null?name:this.beanNameGenerator.generateBeanName(annotatedBeanDefinition, registry));

       //bean注册的holer.

       BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(annotatedBeanDefinition, beanName);

       //使用bean注册工具类进行注册.

       BeanDefinitionReaderUtils.registerBeanDefinition(beanDefinitionHolder, registry);

    }

   

}

这个类里的代码比较多,在这里简单的介绍下:方法postProcessBeanDefinitionRegistry()是用来注册bean的;而具体注册的代码比较是通用的,我们定义一个私有的方法进行注册。

postProcessBeanFactory()bean配置的工厂方法,在这个方法中可以获取到我们所有在postProcessBeanDefinitionRegistry方法中注册的所有bean,在这里我们可以进行属性的设置等操作。

// 这里可以设置属性,例如

       BeanDefinition beanDefinition = beanFactory.getBeanDefinition("dataSourceA");

       MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();

       //加入属性.

       mutablePropertyValues.addPropertyValue("driverClassName", "com.mysql.jdbc.Driver");

       mutablePropertyValues.addPropertyValue("url", "jdbc:mysql://localhost:3306/test");

       mutablePropertyValues.addPropertyValue("username", "root");

       mutablePropertyValues.addPropertyValue("password", "123456");

 

 

 

测试代码:

以直接注入我们的对象,对于同样接口的我们需要指定name

package com.kfit.config;

 

import org.kfit.service.HelloService;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

import com.kfit.demo.Shanhy;

 

@Configuration

publicclass MyConfig {

   

    /**

     *  这里只是测试使用,没有实际的意义.

     */

    @Bean(name="testHelloService")

    public HelloService filterRegistrationBean(@Qualifier("shanhyB") Shanhy shanhy){

       HelloService helloService = new HelloService();

        shanhy.display();

        // 其它处理代码.

        returnhelloService;

    }

   

}

 

使用@Resource 或者 @Autowired并指定@Qualifier 也可以

 

 

package com.kfit.controller;

 

import javax.annotation.Resource;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

 

import com.kfit.demo.Shanhy;

 

/**

 *

 * @author Angel(QQ:412887952)

 * @version v.0.1

 */

@RestController

publicclass HelloController {

 

    @Resource(name = "shanhyA")

    private Shanhy shanhyA;

 

    @Autowired

    @Qualifier("shanhyB")

    private Shanhy shanhyB;

 

    @RequestMapping("/test")

    public String test(){

       shanhyA.display();

       shanhyB.display();

       return"test";

    }

}

访问:http://127.0.0.1:8080/test 查看控制台的打印信息。

 

 

在源代码中由于代码有此系列教程别的章节的代码,请自行忽略阅读,给大家造成的不变请谅解。

 

 

 

 Spring Boot 系列博客】

à悟空学院:https://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/A6ZagYTi

Spring Cloud视频:http://t.cn/A6ZagxSR

SpringBoot Shiro视频:http://t.cn/A6Zag7IV

SpringBoot交流平台:https://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/A6Zad1OH

SpringSecurity5.0视频:http://t.cn/A6ZadMBe

Sharding-JDBC分库分表实战http://t.cn/A6ZarrqS

分布式事务解决方案「手写代码」:http://t.cn/A6ZaBnIr

 

网易云课堂视频最新更新

第十一章 Spring Boot 日志

1、spring boot日志—理论

2、Spring Boot日志-logback

3、Spring Boot日志-log4j2

第十二章 Spring Boot 知识点2

1、spring boot 服务配置和部署

2、Spring Boot 定制URL匹配规则

 

 

历史章节

 

第一章 快速开始

1、Spring Boot之Hello World

2、Spring Boot之Hello World访问404

 

第二章 Spring Boot之JSON

1、spring boot返回json数据

2、Spring Boot完美使用FastJson解析JSON数据

 

第三章 Spring Boot热部署

1、Spring Boot热部署(springloader)

2、springboot + devtools(热部署)

 

第四章 Spring Boot数据库

1、Spring Boot JPA/Hibernate/Spring Data概念

2、Spring Boot JPA-Hibernate

3、Spring Boot Spring Data JPA介绍

4、Spring Boot JdbcTemplate

5、Spring Boot集成MyBatis

 

第五章 web开发

1、全局异常捕捉

2、配置server信息

3、spring boot使用thymeleaf

4、Spring Boot 使用freemarker

5、Spring Boot添加JSP支持

 

第六章 定时任务

1、Spring Boot定时任务

2、Spring Boot 定时任务升级篇(动态修改cron参数)

3、Spring Boot 定时任务升级篇(动态添加修改删除定时任务)

4、Spring Boot 定时任务升级篇(集群/分布式下的定时任务说明)

5、Spring Boot Quartz介绍

6、Spring Boot Quartz在Java Project中使用

7、Spring Boot 集成Quartz普通使用

8、Spring Boot 集成Quartz升级版

9、Spring Boot 集成Quartz二次升级版

10、Spring Boot 集成Quartz-Job如何自动注入Spring容器托管的对象

 

第七章 Spring Boot MyBatis升级篇

1、Spring Boot MyBatis升级篇-注解

2、Spring Boot MyBatis升级篇-注解-自增ID

3、Spring Boot MyBatis升级篇-注解-增删改查

4、Spring Boot MyBatis升级篇-注解-分页查询

5、Spring Boot MyBatis升级篇-注解-分页PageHelper不生效

6、Spring Boot MyBatis升级篇-注解- mybatic insert异常:BindingException: Parameter 'name' not found

7、Spring Boot MyBatis升级篇-注解- #和$符号特别篇

8、Spring Boot MyBatis升级篇-注解-@Result

9、Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案一:<script>

10、Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案二:@Provider

11、Spring Boot MyBatis升级篇-注解-动态SQL-参数问题

12、Spring Boot MyBatis升级篇-注解-特别篇:@MapperScan和@Mapper

13、Spring Boot MyBatis升级篇-XML

14、Spring Boot MyBatis升级篇-XML-自增ID

15、Spring Boot MyBatis升级篇-XML-增删改查

16、Spring Boot MyBatis升级篇-XML-分页查询

17、Spring Boot MyBatis升级篇-XML-分页PageHelper不生效

18、Spring Boot MyBatis升级篇-XML-动态SQL(if test)

19、Spring Boot MyBatis升级篇-XML-注解-初尝试

20、Spring Boot MyBatis升级篇- pagehelper替换为pagehelper-spring-boot-starter

 

第八章 Spring Boot 知识点1

1、Spring Boot 拦截器HandlerInterceptor

2、Spring Boot启动加载数据CommandLineRunner

3、Spring Boot环境变量读取和属性对象的绑定

4、Spring Boot使用自定义的properties

5、Spring Boot使用自定义的properties

6、Spring Boot使用@SpringBootApplication

7、Spring Boot 监控和管理生产环境

 

第十章 Spring Boot 打包部署

1、Spring Boot打包部署((提供Linux的sh文件))

 

第十一章 Spring Boot 日志

1、spring boot日志—理论

2、Spring Boot日志-logback

3、Spring Boot日志-log4j2

 

分享到:
评论
6 楼 林祥纤 2017-05-31  
jj009 写道
林祥纤 写道
jj009 写道
hi 博主你好,看了这篇文章很受启发。
不过有一点想知道,如果基于springboot 还能否 像
在SPRING中那样使用配置文件进行自定义BEAN 和注册到spring管理呢?
还是说在springboot下只能通过这种JAVA编码的方式进行bean的注册


可以的,在有一篇博客有进行说明的!

抱歉啊 没有找到 能否 发下链接



(31)Spring Boot导入XML配置【从零开始学Spring Boot】
5 楼 jj009 2017-05-26  
林祥纤 写道
jj009 写道
hi 博主你好,看了这篇文章很受启发。
不过有一点想知道,如果基于springboot 还能否 像
在SPRING中那样使用配置文件进行自定义BEAN 和注册到spring管理呢?
还是说在springboot下只能通过这种JAVA编码的方式进行bean的注册


可以的,在有一篇博客有进行说明的!

抱歉啊 没有找到 能否 发下链接
4 楼 林祥纤 2017-05-23  
jj009 写道
hi 博主你好,看了这篇文章很受启发。
不过有一点想知道,如果基于springboot 还能否 像
在SPRING中那样使用配置文件进行自定义BEAN 和注册到spring管理呢?
还是说在springboot下只能通过这种JAVA编码的方式进行bean的注册


可以的,在有一篇博客有进行说明的!
3 楼 jj009 2017-05-21  
hi 博主你好,看了这篇文章很受启发。
不过有一点想知道,如果基于springboot 还能否 像
在SPRING中那样使用配置文件进行自定义BEAN 和注册到spring管理呢?
还是说在springboot下只能通过这种JAVA编码的方式进行bean的注册
2 楼 林祥纤 2016-10-02  
需要
qq1488888 写道
在这的registerBean(registry, "shanyA", ShanhyA.class);
       registerBean(registry, "shanyB", ShanhyB.class);的name

应该要和@Resource(name = "shanhyA")  或者 @Qualifier("shanhyB")   对应吗?


需要
1 楼 qq1488888 2016-10-02  
在这的registerBean(registry, "shanyA", ShanhyA.class);
       registerBean(registry, "shanyB", ShanhyB.class);的name

应该要和@Resource(name = "shanhyA")  或者 @Qualifier("shanhyB")   对应吗?

相关推荐

    详解Spring Boot 使用Java代码创建Bean并注册到Spring中

    本篇介绍了Spring Boot 使用Java代码创建Bean并注册到Spring中,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    从零开始学Spring Boot.pdf

    从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf从零开始学Spring Boot.pdf...

    从零开始学Spring Boot

    (17)Spring Boot普通类调用bean【从零开始学Spring Boot】: http://412887952-qq-com.iteye.com/blog/2292388 ...... (35)Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】 ...

    about learning Spring Boot. Spring Boot 教程、技术栈示例代码,快速简单上手教程.zip

    本项目中所有示例均已经更新到 Spring Boot 3.0 Spring Boot 1.X 系列示例代码请看这里:Spring Boot 1.X Spring Boot 2.X 系列示例代码请看这里:Spring Boot 2.X 示例代码 spring-boot-hello:Spring Boot 3.0 ...

    Pro.Spring.Boot.1942270003

    on practical guide for increasing your Spring Framework-based enterprise Java and cloud application productivity while decreasing development time using the Spring Boot productivity suite of tools....

    spring-boot-autoconfigure-2.3.12.RELEASE-API文档-中文版.zip

    赠送jar包:spring-boot-autoconfigure-2.3.12...标签:springframework、boot、spring、autoconfigure、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。

    初识java,用spring Boot学习java .rar

    使用IntelliJ IDEA的创建向导中的Spring Initializer即可创建Spring Boot工程。 在创建时,如果 https://start.spring.io 无响应,可尝试替换为 https://start.springboot.io。 在创建过程中,需要填写并关注的几...

    spring-boot-2.3.12.RELEASE-API文档-中文版.zip

    标签:springframework、boot、spring、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准...

    17. Spring Boot普通类调用bean【从零开始学Spring Boot】

    NULL 博文链接:https://412887952-qq-com.iteye.com/blog/2292388

    java 使用 Swagger 创建一个Spring Boot 的 Web 服务

    java 使用 Swagger 创建一个Spring Boot 的 Web 服务java 使用 Swagger 创建一个Spring Boot 的 Web 服务java 使用 Swagger 创建一个Spring Boot 的 Web 服务java 使用 Swagger 创建一个Spring Boot 的 Web 服务java...

    Beginning Spring Boot 2 Applications and Microservices with the Spring Framework

    Spring is the most popular Java-based framework for building enterprise applications. The Spring framework provides a rich ecosystem of projects to address modern application needs, like security, ...

    spring-boot-autoconfigure-2.0.6.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-boot-autoconfigure-2.0.6....标签:spring、autoconfigure、springframework、boot、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵

    spring-boot-configuration-processor-2.3.12.RELEASE-API文档-中文版.zip

    赠送源代码:spring-boot-configuration-processor-2.3.12.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-boot-configuration-processor-2.3.12.RELEASE.pom; 包含翻译后的API文档:spring-boot-...

    SpringBoot学习笔记完整教程

    Spring Boot 学习笔记,包括底层实现原理及代码实战,非常齐全,助你快速打通 Spring Boot 的各个环节。 1. Spring boot helloworld 2. Spring boot 返回 json 数据 3. Spring boot 使用其他 json 转换框架 4. ...

    Spring bean 动态注册,jar包热替换

    Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class...测试示例中是spring boot 的部分代码,动态加载的内容为接口实现类,且初始化时加载本地的实现类,动态加载后改为非程序加载目录中的jar实现类。

    Pivotal团队提供的微框架Spring Boot.zip

    快速在 Java 代码中测试和使用 Spring Boot 的方法:import org.springframework.boot.*; import org.springframework.boot.autoconfigure.*; import org.springframework.web.bind.annotation.*; @...

    Pro Spring Boot(Apress,2016)

    on practical guide for increasing your Spring Framework-based enterprise Java and cloud application productivity while decreasing development time using the Spring Boot productivity suite of tools....

    使用Spring Boot的小型诊所信息系统,毕业设计Java版.zip

    使用Spring Boot的小型诊所信息系统,毕业设计Java版.zip使用Spring Boot的小型诊所信息系统,毕业设计Java版.zip使用Spring Boot的小型诊所信息系统,毕业设计Java版.zip使用Spring Boot的小型诊所信息系统,毕业...

Global site tag (gtag.js) - Google Analytics