spring配置类,即在类上加@Configuration注解,使用这种配置类来注册bean,效果与xml文件是完全一样的,只是创建springIOC容器的方式不同:

//通过xml文件创建springIOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-beans.xml");
//通过配置类创建springIOC容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);

0. 传统的xml配置文件方式注册bean类

单个注册

<!--单实例模式-->
<bean id="person" class="cn.monolog.entity.Person" scope="singleton" />
<!--多实例模式-->
<bean id="book" class="cn.monolog.entity.Book" scope="prototype" />

扫描批量注册,只能注册加了组件注解(@Repository、@Service、@Controller、@Component)的类

<!--通过扫描批量注册加了组件注解的bean-->
<context:component-scan base-package="cn.monolog.entity" />

1. 使用配置类单个注册

①在配置类上加@Configuration注解

②在方法上加@Bean注解,bean的id默认为方法名,如果需要自定义id,则在该注解上加value属性

③如果需要指定bean的作用域,则还要在方法上加@Scope注解,如果不加该注解,则默认为单例模式

该注解的value属性有如下几种常用取值(均为字符串格式)

单例模式(singleton): 创建IOC容器时即创建bean对象,以后每次取值都是取的这个bean对象

原型模式(protortype): 创建IOC容器时不创建bean对象,以后每次取值时再分别创建

另外还有request、session、global session

④对于单例模式,还可以加@Lazy注解,即懒加载,表示在创建IOC容器时并不创建bean对象,而是在第一次获取bean对象时才创建,之后再获取bean对象时不再创建,因此仍然是单实例

懒加载的作用:加快SpringIOC容器的启动速度、解决循环依赖的问题

/**
* springIOC配置容器类
* 用于代替spring-beans.xml,生成bean对象
*/
@Configuration
public class BeanConfig { //生成Person实例
@Bean(value = "person")
public Person person() {
String name = "张三";
int age = 29;
return new Person(name, age);
} /**
* 使用单实例模式生成Book实例
* 这时,是在springIOC容器启动时就创建了bean实例,然后每次获取实例时,直接从容器中拿
*/
@Bean(value = "singleBook")
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public Book singleBook() {
String name = "hello world";
double price = 29.00D;
return new Book(name, price);
} /**
* 使用多实例模式生成Book实例
* 这时,启动springIOC容器时并未创建bean实例,而是每次获取bean实例时再调用该方法去新创建
*/
@Bean(value = "multipleBook")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Book multipleBook() {
String name = "hello world";
double price = 29.00D;
return new Book(name, price);
} /**
* 使用懒加载模式生成bean实例
* 懒加载只对单实例模式有效
* 本来,单实例模式,是在启动springIOC容器时创建bean实例
* 使用懒加载后,在启动springIOC容器时并不创建bean实例,而是在首次获取bean时才创建
*/
@Bean(value = "person")
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Lazy
public Person person() {
return new Person("刘能", 53);
}
}

2. 使用配置类扫描批量注册,只能注册加了组件注解(@Repository、@Service、@Controller、@Component)的类

①在配置类上加@Configuration注解

②在配置类上加@ComponentScan注解,并在其basePackages属性(字符串数组类型)中写明要扫描的包,可以写1个或多个包,如果想排除某些类,可以写在excludeFilter属性中

/**
* 通过扫描批量注册加了组件注解的bean
* 并排除Dog类
*/
@Configuration
@ComponentScan(basePackages = {"cn.monolog.entity", "cn.monolog.service", "cn.monolog.dao"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {Dog.class})})
public class BeanConfig {
}

3. 按条件注册

①在配置类上加@Configuration注解

②在方法上加@Bean注解,bean的id默认为方法名,如果需要自定义id,则在该注解上加value属性

③在方法上加@Conditional注解,该注解的参数是字节码数组,什么样的类的字节码呢?必须是实现了Condition接口的。使用时,需要自定义1个或多个Condition的实现类,并在其实现方法中定义生效条件,当满足生效条件时,才会去注册该bean类

import org.springframework.context.annotation.Condition;

/**
* springIOC条件注册中的条件类
*/
public class JuventusCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取bean注册器
BeanDefinitionRegistry registry = context.getRegistry(); //判断该IOC容器中是否含有id为juventus的组件,如果是,则生效
if (registry.containsBeanDefinition("juventus")) {
return true;
} return false;
}
}
/**
* 按条件注册bean类
*/
@Configuration
public class BeanConfig { /**
* 按条件生成名字为ronaldo的Person对象
* 条件为写在JuventusCondition类中
*/
@Bean(value = "ronaldo")
@Scope(value = SCOPE_SINGLETON)
@Conditional({JuventusCondition.class})
public Person ronaldo() {
return new Person("ronaldo", 34);
}
}

4. 使用导入方式注册

①在配置类上加@Configuration注解

②在配置类上加@Import注解,该注解的value属性为字节码数组,可以接收以下三种类的字节码

要注册的类;

实现了ImportSelector接口的自定义类,其实现方法的返回值为要注册的类的全限定名数组;

实现了ImportBeanDefinitionRegistrar的自定义类,在其实现方法中,使用BeanDefinitionRegistry手动注册,前面两种方式注册的bean的id只能是类的全限定名,只有这种方式可以自定义bean的id;

import org.springframework.context.annotation.ImportSelector;

/**
* 使用import注解注册bean的选择器
* 注意该方法可以返回空数组,但不能返回null,因为在后续源码中会获取返回值的长度
* 而且这里只能用类的全限定名
*/
public class ColorImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String[] results = {"cn.monolog.entity.Green", "cn.monolog.entity.Pink"};
return results;
}
}
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;

/**
* 使用import注解注册bean时,自定义bean选择器
* 在该类的实现方法中,使用bean注册器手动注册
* 注意,如果多次为同一个id注册bean,后面的会覆盖前面的
*/
public class ColorDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//判断该容器中是否已经存在id为yellow的组件,如果不存在,则手动注册
String id = "yellow";
if (!registry.containsBeanDefinition(id)) {
//bean的id
String beanName = "yellow";
//bean的类型
BeanDefinition beanDefinition = new RootBeanDefinition(Yellow.class);
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
}
/**
* springIOC容器配置类
* 使用import注解注册bean
* 该注解可以接收三种参数
* 1.要注册的类的字节码
* 2.ImportSelector的自定义实现类的字节码,在其实现方法中,将要注册的类的全限定名写入返回数组
* 3.ImportBeanDefinitionRegistrar的自定义实现类的字节码,在其实现方法中,使用bean注册器手动注册
* 其中,前两种方式注册的bean的id只能是该类的全限定名
* 第三种方式注册的bean类可以自定义id
*/
@Configuration
@Import({Red.class, ColorImportSelector.class, ColorDefinitionRegistrar.class})
public class BeanConfig {
}

5. 使用工厂模式注册

工厂模式与第1条(单个注册)的方法完全相同,唯一的特别之处在于,注册的是一个"工厂类",即实现了FactoryBean<T>接口的自定义类,这种类的特点是,在IOC容器中直接按id获取的并不是它本身的对象,而是它内部注册的bean类的对象。要想获取它本身的对象,要在id前面拼接"&"符号。

FactoryBean<T>接口有三个方法:

getObject——用于注册真正的bean类

getObjectType——用于获取bean类的类型,即泛型T

isSingleton——注册的bean类是否为单例模式

import org.springframework.beans.factory.FactoryBean;

/**
* 工厂类
*/
public class ColorFactoryBean implements FactoryBean<Color> { //注册bean
@Override
public Color getObject() throws Exception {
return new Color("#FFF");
} //获取bean的类型
@Override
public Class<?> getObjectType() {
return Color.class;
} //是否单实例模式
@Override
public boolean isSingleton() {
return true;
}
}

使用spring配置类代替xml配置文件注册bean类的更多相关文章

  1. Spring中加载xml配置文件的六种方式

    Spring中加载xml配置文件的六种方式 博客分类: Spring&EJB XMLSpringWebBeanBlog  因为目前正在从事一个项目,项目中一个需求就是所有的功能都是插件的形式装 ...

  2. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...

  3. 使用spring框架,用xml方式进行bean装配出现“The fully qualified name of the bean's class, except if it serves...”

    使用spring框架,用xml方式进行bean装配出现“The fully qualified name of the bean's class, except if it serves...”. 原 ...

  4. Spring中,applicationContext.xml 配置文件在web.xml中的配置详解

    一.首先写一下代码结构. 二.再看web.xml中的配置情况. <?xml version="1.0" encoding="UTF-8"?> < ...

  5. Spring编译后没有xml配置文件解决方法

    问题描述 在使用Maven来构建Spring项目的时候,使用下面代码来读取Spring配置文件. ClassPathXmlApplicationContext context = new ClassP ...

  6. [spring]xml配置文件中bean属性的两种写法(p:configLocation <=> <property name="configLocation"/>)

    1.当作bean节点的属性:p:configLocation: <!-- mybatis文件配置,扫描所有mapper文件 --> <bean id="sqlSession ...

  7. 模拟Spring中applicationContext.xml配置文件初始化bean的过程

    package com.xiaohao.action; import java.io.File; import java.lang.reflect.Method; import java.util.C ...

  8. C#中读写Xml配置文件常用方法工具类

    场景 有时需要使用配置文件保存一些配置的属性,使其在下次打开时设置仍然生效. 这里以对xml配置文件的读写为例. 1.读取XML配置文. 2.写入XML配置文件. 3.匹配 XPath 表达式的第一个 ...

  9. Spring系列11:@ComponentScan批量注册bean

    回顾 在前面的章节,我们介绍了@Comfiguration和@Bean结合AnnotationConfigApplicationContext零xml配置文件使用Spring容器的方式,也介绍了通过& ...

随机推荐

  1. QRCode.js一个生成二维码的javascript库

    前言 最近在开发中遇到一个需求:将后端返回的链接转换成二维码,那么如何来实现呢?我们可以使用QRCode.js来解决这一问题 什么是 QRCode.js? QRCode.js 是一个用于生成二维码的 ...

  2. wordpress添加index页面跳转链接

    1. 制作page页面 1.1 在themes下的主题目录新建一个page页面 1.2 在wordpress后台新建页面跟在目录页面中相同名字的页面文件 1.3 复制后台页面中的古定链接 1.4 在i ...

  3. [七月挑选]Tomcat使用命令行启动之指定jdk版本

    title: Tomcat使用命令行启动之指定jdk版本 准备好环境,jdk和tomcat. 主要步骤 1.找到Tomcat/bin/catalina.bat文件. 2.在文件前端添加如下. set ...

  4. 【转】linux lost+found文件夹

    lost+found这个目录一般情况下是空的,当系统非法关机后,如果你丢失了一些文件,在这里能找回来 用来存放fsck过程中部分修复的文件的 如果你运行fsck命令(文件系统检查和修复命令),它也许会 ...

  5. Tensorflow fintune

    https://zhuanlan.zhihu.com/p/42183653 tf2.0中有更简单的做法,和keras一样

  6. 写api接口神器--带你5分钟了解swagger

    随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染.先后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远. 前端和后端的唯一联系,变成了API接口:API文档变成了 ...

  7. MySQL常见的三种存储引擎

    原文链接:https://www.cnblogs.com/yuxiuyan/p/6511837.html 简单来说,存储引擎就是指表的类型以及表在计算机上的存储方式. 存储引擎的概念是MySQL的特点 ...

  8. spark-2.1.1 yarn(高可用)搭建

    一.概述 spark分布式搭建方式大致分为三种:standalone.yarn.mesos.三种分类的区别这里就不一一介绍了,不明白可自行了解.standalone是官方提供的一种集群方式,企业一般不 ...

  9. for-in语句和with语句、break和continue语句

    for-in语句 for-in语句是一种精准迭代语句,可以用来枚举对象的属性,用以遍历一个对象的全部属性. for…in声明用于对数组或者对象的属性进行循环操作: for…in循环中的代码每执行一次, ...

  10. php array_push()函数 语法

    php array_push()函数 语法 作用:向第一个参数的数组尾部添加一个或多个元素(入栈),然后返回新数组的长度.博智达 语法:array_push(array,value1,value2.. ...