`

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")   对应吗?

相关推荐

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

    Spring Boot普通类调用bean【从零开始学Spring Boot】”旨在指导初学者如何在非Spring管理的类中访问和使用Spring容器中的bean。下面将详细讲解这个主题。 首先,了解Spring Boot的基础概念是必要的。Spring Boot...

    27. Spring Boot Junit单元测试【从零开始学Spring Boot】

    Spring Boot Junit单元测试【从零开始学Spring Boot】"的主题,深入探讨Spring Boot中Junit单元测试的使用方法和最佳实践。 首先,我们要了解什么是单元测试。单元测试是一种针对软件中的最小可测试单元(如方法)...

    31. Spring Boot导入XML配置【从零开始学Spring Boot】

    在本篇【从零开始学Spring Boot】系列教程中,我们将深入探讨如何在Spring Boot项目中导入并使用XML配置。Spring Boot以其简化Spring应用的初始搭建以及开发过程而闻名,通常推崇的是Java配置而非XML配置。然而,在...

    38. Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】

    在Spring Boot的配置类中,启用Spring Session并指定使用Redis作为存储策略: ```java @Configuration public class SessionConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { ...

    从零开始学Spring Boot

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

    15. Spring Boot使用Druid和监控配置【从零开始学Spring Boot】

    在本篇【从零开始学Spring Boot】系列中,我们将探讨如何在Spring Boot项目中集成并配置Druid数据源以及其监控功能。Druid是一个强大的数据库连接池,它提供了丰富的监控、扩展性以及性能优化特性。Spring Boot简化...

    16. Spring Boot使用Druid(编程注入)【从零开始学Spring Boot】

    在本篇【从零开始学Spring Boot】系列中,我们将探讨如何在Spring Boot项目中使用Druid数据源进行编程注入。Druid是一个优秀的数据库连接池,它提供了强大的监控和扩展功能,是许多企业级应用首选的数据源解决方案。...

    47. Spring Boot发送邮件【从零开始学Spring Boot】

    在本篇博文中,我们将深入探讨如何使用Spring Boot发送电子邮件,这是Spring Boot框架的一个非常实用的功能,可以帮助开发者轻松实现企业级应用中的邮件服务。通过学习本文,你可以掌握Spring Boot集成...

    39.1 Spring Boot Shiro权限管理【从零开始学Spring Boot】

    在Spring Boot中,我们可以通过创建一个名为`ShiroConfig`的类并使用`@Configuration`和`@EnableWebSecurity`注解来实现。在这个配置类中,我们可以定义安全策略、过滤器链、Realm(用于身份验证和授权)等。 ```...

    从零开始学spring boot

    《从零开始学Spring Boot》是一本面向初学者的指南,旨在帮助编程新手全面理解并掌握Spring Boot这一强大的Java开发框架。Spring Boot是Spring生态系统的一部分,它简化了配置,提供了快速构建应用程序的能力,使得...

    37. Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】

    在本教程中,我们将深入探讨如何使用Spring Boot集成EHCache来实现高效的缓存机制。Spring Boot简化了配置过程,使得我们可以快速地将EHCache引入到我们的应用中,从而提高应用程序的性能,减少对数据库或其他资源的...

    39.2. Spring Boot Shiro权限管理【从零开始学Spring Boot】

    在本教程中,我们将深入探讨如何使用Spring Boot和Apache Shiro进行权限管理。Spring Boot以其简洁的配置和快速的应用开发能力而闻名,而Shiro则是一个强大的安全管理框架,提供了认证、授权、会话管理和安全加密等...

    2. [视频]Spring Boot返回json数据【从零开始学Spring Boot】

    在本节【从零开始学Spring Boot】的视频教程中,我们将深入探讨如何在Spring Boot应用中处理JSON数据。Spring Boot作为一个快速开发框架,极大地简化了创建和部署Java web应用程序的过程,同时也为处理HTTP响应提供...

    26. 改变自动扫描的包【从零开始学Spring Boot】

    改变自动扫描的包【从零开始学Spring Boot】”涉及到的是Spring Boot框架中的组件扫描机制。在Spring Boot中,自动配置是其核心特性之一,它能够根据项目依赖来自动配置相应的Bean。默认情况下,Spring Boot会扫描...

    从零开始Spring Boot

    从零开始Spring Boot,通过实战快速入门。Spring Boot不是一门新技术,所以不用紧张。从本质上来说,Spring Boot就是Spring,它做了那些没有它你也会去做的Spring Bean配置。它使用“习惯优于配置”(项目中存在大量...

    9. 使用JdbcTemplate【从零开始学Spring Boot】

    在本节中,我们将深入探讨如何在Spring Boot项目中使用JdbcTemplate进行数据库操作。JdbcTemplate是Spring框架提供的一种简化数据库访问的工具,它通过提供一套模板方法,使得开发者可以更安全、更方便地执行SQL语句...

    spring boot入门--创建项目到数据库连接

    在这个“spring boot入门--创建项目到数据库连接”的教程中,我们将深入探讨如何从零开始创建一个 Spring Boot 项目,并实现与数据库的连接。 首先,我们需要理解 Spring Boot 的核心特性。它内置了一个内嵌的...

Global site tag (gtag.js) - Google Analytics