已经好久没有讲一些基础的知识了,这一小节来点简单的,这也是为下节的在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. webview 播放H5视频问题 黑屏 只有声音没有画面

    android 用webview 播放网络视频怎控制播放按键? 在代码中加入webview.getSettings().setJavaScriptEnabled(true);//支持jswebview ...

  2. P2453 [SDOI2006]最短距离 dp

    自己想出来了!这个dp比较简单,而且转移也很简单,很自然,直接上代码就行了. 题干: 一种EDIT字母编辑器,它的功能是可以通过不同的变换操作可以把一个源串X [l..m]变换为新的目标串y[1..n ...

  3. 实现https

    实现https 环境 1.三台主机分别为A,B,C. 2.A主机设置为CA和DNS服务器,ip为192.168.213.129 3.B主机为client,ip为192.168.213.253 4.C主 ...

  4. PCB Winform中的WebBrowser扩展拖放(拖拽)功能 实现方法

    我们在Winform支持网页通常增加WebBrowser控件实现,相当于内嵌浏览器浏览网页使用, 而此WebBrowser默认情况是文件拖入功能是不支持的, 如何才能支持呢.在这里介绍如何实现方法 一 ...

  5. Reward(toposort)

    http://acm.hdu.edu.cn/showproblem.php?pid=2647 #include <stdio.h> #include <string.h> #i ...

  6. POJ 3855 计算几何·多边形重心

    思路: 多边形面积->任选一个点,把多边形拆成三角,叉积一下 三角形重心->(x1+x2+x3)/3,(y1+y2+y3)/3 多边形重心公式题目中有,套一下就好了 计算多边形重心方法: ...

  7. Android App签名(为apk签名)

    最近有朋友问到 android 签名的问题,所以转一篇给大家分享: 这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 1.签名的意义 为了保证每个应用程序开 ...

  8. 移动web——touch事件介绍

    基本概念 1.在移动web端点击事件或者滑动屏幕.捏合等动作都是由touchstar.touchmove.touchend这三个事件组合在一起使用的 2.click事件在移动端会有0.2秒的延迟,下面 ...

  9. selenium的三种等待时间

    //隐式等待(20秒以内没哥一段时间就会去找元素,如果没找大也不会报错,过了20s才会报错) //driver.manage().timeouts().implicitlyWait(20, TimeU ...

  10. Python常用的标准库及第三方库

    标准库Python拥有一个强大的标准库.Python语言的核心只包含数字.字符串.列表.字典.文件等常见类型和函数,而由Python标准库提供了系统管理.网络通信.文本处理.数据库接口.图形系统.XM ...