已经好久没有讲一些基础的知识了,这一小节来点简单的,这也是为下节的在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. MSP430:定时器学习TimerA

    4. 定时器TA 一.时钟源1.时钟源:ACLK/SMCLK 外部TACLK/INCLK2.分频:1/2/4/8 当 (注:TACLR 置位时,分频器复位) 二.计数模式通过设置MCx可以设置定时器的 ...

  2. vuejs 中如何优雅的获取 Input 值

    http://www.sunzhongwei.com/how-to-get-input-value-in-vuejs

  3. 【转载】SSH框架总结(框架分析+环境搭建+实例源码下载)

    首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层Web应用程序. 集成SSH框 ...

  4. css bug(ie6兼容问题)

    二.五大浏览器内核1.trident(MSHTML)(三叉戟:三叉线,三齿鱼叉) Gecko (壁虎) presto(迅速的) webkit(safari内核,Chrome内核原型,他是苹果公司自己的 ...

  5. 开启和安装Kubernetes 基于Docker For Windows

    0.最近发现,Docker For Windows Stable在Enable Kubernetes这个问题上是有Bug的,建议切换到Edge版本,并且采用下文AliyunContainerServi ...

  6. 根据JSON创建对应的HIVE表

    本文提供一种用SCALA把JSON串转换为HIVE表的方法,由于比较简单,只贴代码,不做解释.有问题可以留言探讨 package com.gabry.hiveimport org.json4s._im ...

  7. Java里边什么是值传递和引用传递?两个有什么区别

    学过java基础的人都知道,在java中参数的传递过程中有值传递和应用传递,那么这两个到底有什么区别呢,下面我通过例子为大家详细的介绍下. 我们都知道Java中有八种数据类型,基础数据类型分别是:by ...

  8. 记一次MySQL索引优化

    两张表是主(CHECK_DRAWINGS)从(CHECK_DRAWINGS_IMG)关系. CHECK_DRAWINGS,主表数据 3591条. SELECT COUNT(*) FROM CHECK_ ...

  9. SCOI2014总结

    似乎还没有写过SCOI的总结,今天补上,权当填坑. PS:CDQZ的看到了不要到处黑 SCOI-2014应该算是我的小高考,感觉拿住一本招的瓶颈就在这里.加之NOIp只有400分有点拖后腿,所以很早就 ...

  10. 软件图标显示不正常【win7企业版】

    现象: 原因: 图标缓存没有把该软件图标建立起来 解决: 一. 1.找到 IconCache.db 2.你要把电脑隐藏文件打开不然找不到这个文件的,组织—文件夹及搜索选项——查看——显示隐藏文件.文件 ...