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

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

与XML和Annotation两种配置方式不同点在于:

前两种方式XML和Annotation的配置方式为预定义方式,即开发人员通过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初始化创建之前启动,如果Spring的bean需要的其他第三方中的组件,我们在这里将其注入给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 系列博客】

0)前言【从零开始学Spring Boot】 :

http://412887952-qq-com.iteye.com/blog/2291496

(1)spring boot起步之Hello World【从零开始学Spring Boot】:

http://412887952-qq-com.iteye.com/blog/2291500

(2)Spring Boot返回json数据【从零开始学Spring Boot】

http://412887952-qq-com.iteye.com/blog/2291508

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

http://412887952-qq-com.iteye.com/blog/2292362

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

http://412887952-qq-com.iteye.com/blogs/2292376

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

http://412887952-qq-com.iteye.com/blog/2292388

......

(35)Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】

http://412887952-qq-com.iteye.com/blog/2294942

更多查看博客:http://412887952-qq-com.iteye.com/

(41)Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】的更多相关文章

  1. Spring Boot 使用Java代码创建Bean并注册到Spring中

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/catoop/article/details/50558333 声明同一个类下的多个实例: packa ...

  2. 21.Spring Boot 使用Java代码创建Bean并注册到Spring中

    转自:https://blog.csdn.net/catoop/article/details/50558333

  3. Spring Boot 使用Java代码创建Bean并注冊到Spring中

    从 Spring3.0 開始,添加了一种新的途经来配置Bean Definition,这就是通过 Java Code 配置 Bean Definition. 与Xml和Annotation两种配置方式 ...

  4. Spring实战——通过Java代码装配bean

    上篇说的是无需半行xml配置完成bean的自动化注入.这篇仍然不要任何xml配置,通过Java代码也能达到同样的效果. 这么说,是要把上篇的料拿出来再煮一遍? 当然不是,上篇我们几乎都在用注解的方式如 ...

  5. Spring 之通过 Java 代码装配 bean

    [关于IoC的几点认识] 1.面向接口编程 --> 每层只向上层提供接口 2.inversion of control (IoC)  -->参考百度百科 3.DI是IoC的一种实现方式 [ ...

  6. Spring装配之——JAVA代码装配Bean

    首先创建几个普通的JAVA对象,用于测试JAVA代码装配bean的功能. package soundsystemJava; //作为接口 定义了CD播放器对一盘CD所能进行的操作 public int ...

  7. (29)Spring boot 文件上传(多文件上传)【从零开始学Spring Boot】

    文件上传主要分以下几个步骤: (1)新建maven java project: (2)在pom.xml加入相应依赖: (3)新建一个表单页面(这里使用thymleaf); (4)编写controlle ...

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

    转载:http://blog.csdn.net/linxingliang/article/details/52013017 我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个 ...

  9. 70.打印所有Spring boot载入的bean【从零开始学Spring Boot】

    [从零开始学习Spirng Boot-常见异常汇总] 问题的提出: 我们在开发过程当中,我们可能会碰到这样的问题:No qualifying bean  就是我们定义的bean无法进行注入,那到底是什 ...

随机推荐

  1. StackExchange.Redis 使用资料

    在StackExchange.Redis中最重要的对象是ConnectionMultiplexer类, 它存在于StackExchange.redis命名空间中.这个类隐藏了Redis服务的操作细节, ...

  2. 【BZOJ 3032】 七夕祭

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3032 [算法] 交换左右两个相邻格子的摊点,不会改变这一行的摊点个数 交换上下两个相 ...

  3. PCB 钻孔补偿那点事

    没有优秀的个人,只有优秀的团队,在团队共同的协作下,PCB CAM自动化[net处理]与[钻孔处理] 第一阶段开发项完成了,,后续工作可以转向PCB规则引擎开发了.这里说说PCB工程钻孔补偿的那点事, ...

  4. [Swift通天遁地]六、智能布局-(7)通过Group(组)命令实现对多个视图的统一约束

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. [Swift通天遁地]九、拔剑吧-(2)在项目中使用大量美观的图标

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. easyui DatagrId 的实例讲解

    下面是代码实现 @{    ViewBag.Title = "人员查找";    ViewBag.LeftWidth = "200px";    ViewBag ...

  7. 《Typecript 入门教程》 3、接口

    转载:<TypeScript 中文入门教程> 3.接口 介绍 TypeScript的核心原则之一是对值所具有的shape进行类型检查. 它有时被称做“鸭式辨型法”或“结构性子类型化”. 在 ...

  8. nginx入门学习

    1.yum解决编译nginx所需的依赖包,之后你的nginx就不会报错了 yum install gcc patch libffi-devel python-devel zlib-devel bzip ...

  9. mongo3.4 配置文件 注意事项

    给mongo配置文件坑了好久,今天终于解决了.写个博客,庆祝一下. mongo3.4 版本,我是用YAML格式的配置文件. 一开始,配置之后,启动服务的时候,老是提示:“unrecognized op ...

  10. CSS——float

    float:就是在于布局,首先要介绍的是文档流(标准流),之后是浮动布局. 文档流:元素自上而下,自左而右,块元素独占一行,行内元素在一行上显示,碰到父集元素的边框换行. 浮动布局: 1.float: ...