Spring IOC容器组件注入的几种方式

整理一下之前Spring的学习笔记,大致有一下几种Spring注入到容器中的方法:

1)、配置在xml的方式。

2)、开启包扫描@ComponentScan使用@Component,@Service,@Controller,@Repository(其实后三个都继承@Component)注册组件到spring容器里面

3)、使用@Bean注入

4)、使用@Import快速导入组件

@Configuration

​ 声明为配置类,与bean.xml一致

XML方式注入

Sping最开始的用法,先定义好xml文件,使用ClassPathXmlApplicationContext()加载指定xml文件就创建好容器了,当Bean过多的时候,使用xml配置就显得比较繁琐,所以在现在的大环境下,这种注入方法已经过时了,就简单的提一下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.test.SpringCoreTest.test00.bean.User"><property name="name" value="Tom"></property><property name="age" value="12"></property></bean></beans>

@ComponentScan

需和@Configuration注解一起使用,与xml当中的<context:component-scan base-package="" />一致,表示扫描指定包下的类将带有@Component注解的类全部扫描到容器当中

有几个常用的参数需了解一下:

basePackages: 扫描指定包下的类并且注入到spring容器里面

useDefaultFilters:是否使用默认过滤器,和excludeFilters、includeFilters配置一起使用

includeFilters:包含过滤器为过滤的内容,当useDefaultFilters为false的时候才生效

excludeFilters:去除指定过滤器过滤的内容,当useDefaultFilters为true的时候才能生效

过滤器为@ComponentScan的内部注解类@Filter:

      classes:指定类,与type搭配使用

​       type:过滤器的类型org.springframework.context.annotation.FilterType.class枚举类中(共有五种,仅记录三种经常使用的类型)

           ​ ANNOTATION:指定过滤哪些注解,例如@Controller

           ​ ASSIGNABLE_TYPE:指定过滤哪些类

           ​ CUSTOM:自定义过滤器,可继承TypeFilter接口,实现match方法

示例:

public class SpringTest01Filter implements TypeFilter {/*** @param metadataReader 读取当前扫描类的信息* @param metadataReaderFactory 可以获取其他任何类的信息*/public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)throws IOException {//获取当前注解信息ClassMetadata classMetadata = metadataReader.getClassMetadata();//获取当前扫描类的信息String className = classMetadata.getClassName();System.out.println("====>>>>"+className);if(className.contains("er"))//如果当前扫描类信息包含er的时候,注入到Spring容器return true;elsereturn false;}}//配置类
@ComponentScan(basePackages="com.test.SpringCoreTest.test01.config",includeFilters= {@Filter(type = FilterType.CUSTOM,classes= {SpringTest01Filter.class})
},useDefaultFilters=true)
@Configuration

这里会有个问题,为什么在使用过滤器的时候对useDefaultFilters有要求?源码中解析:

ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//该段代码中获取了useDefaultFilters的值
//进入该类中
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;if (useDefaultFilters) {registerDefaultFilters();//useDefaultFilters为true时,该方法开启了注册默认过滤器的方法}setEnvironment(environment);setResourceLoader(resourceLoader);}//进入到registerDefaultFilters方法里面
protected void registerDefaultFilters() {//执行了当前方法重置了includeFilters包含的过滤器,导致带有Component注解的类都会加载到容器里面,所以在useDefaultFilters为true的情况下includeFilters失效的原因在此this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}}

@Bean

需和@Configuration一起使用,容器中的key为方法名,bean为返回的对象,默认为单例。示例:

@Configuration
public class SpringConfig01 {@Beanpublic User user() {return new User();}//....
}

以下三个注解可以和@Bean一起使用:

@Scope

​ 指定容器组件类型

​ prototype:多例模式,当容器创建时,并不会创建对象,而是在调用时创建一个新的对象

​ singleton:单例模式,容器创建时,对象也会创建

​ request:主要是针对web应用,每提交一次请求,都回去创建一个对象

​ session:针对web应用,创建一个session创建一个对象

@Lazy

​ 懒加载只有当前组件第一次被调用的时候才会去创建对象,针对单例模式

@Conditional

​ 可指定在某些条件下,才能将当前组件注入到容器,

​ 参数为继承org.springframework.context.annotation.Condition.class的实现类

/*** @param context 可以使用ApplicationContext(上下文)* @param metadata 可以获取到注解信息*/public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {//获取到BeanFactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory();//可获取环境参数,如jvm环境,spring环境等等Environment environment = context.getEnvironment();String osName = environment.getProperty("os.name");if(osName.contains("Windows"))//如果当前环境为window,则创建当前组件并加载到容器中return true;return false;}

@Import

​ 快速导入组件,共三种形式,这个算是一个比较主要的注入方式吧,在Spring中,需要做一些扩展的时候都会需要用到这个,比如:mybatis-spring融合,开启AOP功能等使用的就是这里的第三种方式

1)、@Import(value = { Dog.class,Cat.class })//快速导入到容器中,以类的全路径作为bean的ID

2)、@Import(value = { SpringTest03ImportSelector.class })//实现ImportSelector接口

public class SpringTest03ImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata importingClassMetadata) {//返回为类的全类名return new String [] {};//注意一下,这边必须返回一个空的数组,不然启动报错空指针异常}}//在源码org.springframework.context.annotation.ConfigurationClassParser.class类中
private Collection<SourceClass> asSourceClasses(String... classNames) throws IOException {List<SourceClass> annotatedClasses = new ArrayList<>(classNames.length);//这里的classNames为之前ImportSelector返回的数组,为null的话即报错for (String className : classNames) {annotatedClasses.add(asSourceClass(className));}return annotatedClasses;}

3)、@Import(value = { SpringTest03ImportBeanDefinitionRegistrar.class })//实现ImportBeanDefinitionRegistrar接口,所有的bean注册都会使用到该接口进行注册

/*** @param importingClassMetadata 当前类的注解信息 * @param registry BeanDefinition的注册类* 可做条件修改*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean b1 = registry.containsBeanDefinition("user");if(b1) {registry.registerBeanDefinition("pig", new RootBeanDefinition(Pig.class));}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我们是如何拿下Google和Facebook Offer的?

http://posts.careerengine.us/p/57c3a1c1a09633ee7e57803c 大家好&#xff0c;我是小高&#xff0c;CMU CS Master&#xff0c;来Offer第一期学员&#xff0c;2014年初在孙老师的带领下我在几个月的时间内进入了Yahoo&#xff0c;并工作了近2年。2016年初&#xff0c;Yahoo工作…

Spring中BeanFactory和FactoryBean的区别

先介绍一下Spring的IOC容器到底是个什么东西&#xff0c;都说是一个控制反转的容器&#xff0c;将对象的控制权交给IOC容器&#xff0c;其实在看了源代码之后&#xff0c;就会发现IOC容器只是一个存储单例的一个ConcurrentHashMap<String, BeanDefinition> BeanDefiniti…

python中数字和字符串可以直接相加_用c语言或者python将文件中特定字符串后面的数字相加...

匿名用户1级2014-08-31 回答代码应该不难吧。既然用爬虫爬下来了&#xff0c;为什么爬取数据的时候没做处理呢。之前用过Scrapy爬虫框架&#xff0c;挺好用的&#xff0c;你可研究下。代码&#xff1a;#!codingutf-8import osimport reimport random# 获取当前目录文件列表def …

Spring中Aware的用法以及实现

Aware 在Spring当中有一些内置的对象是未开放给我们使用的&#xff0c;例如Spring的上下文ApplicationContext、环境属性Environment&#xff0c;BeanFactory等等其他的一些内置对象&#xff0c;而在我们可以通过实现对应的Aware接口去拿到我们想要的一些属性&#xff0c;一般…

c#字符型转化为asc_C#字符串和ASCII码的转换

//字符转ASCII码&#xff1a;public static int Asc(string character){if (character.Length 1){System.Text.ASCIIEncoding asciiEncoding new System.Text.ASCIIEncoding();int intAsciiCode (int)asciiEncoding.GetBytes(character)[0];return (intAsciiCode);}else{thr…

topcoder srm 625 div1

problem1 link 假设第$i$种出现的次数为$n_{i}$&#xff0c;总个数为$m$&#xff0c;那么排列数为$T\frac{m!}{\prod_{i1}^{26}(n_{i}!)}$ 然后计算回文的个数&#xff0c;只需要考虑前一半&#xff0c;得到个数为$R$&#xff0c;那么答案为$\frac{R}{T}$. 为了防止数字太大导致…

Spring的组件赋值以及环境属性@PropertySource

PropertySource 将指定类路径下的.properties一些配置加载到Spring当中&#xff0c; 有个跟这个差不多的注解PropertySources Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented public interface PropertySources {PropertySource[] value();} 使用…

python语音识别框架_横评:五款免费开源的语音识别工具

编者按&#xff1a;本文原作者 Cindi Thompson&#xff0c;美国德克萨斯大学奥斯汀分校(University of Texas at Austin)计算机科学博士&#xff0c;数据科学咨询公司硅谷数据科学(Silicon Valley Data Science&#xff0c;SVDS)首席科学家&#xff0c;在机器学习、自然语言处理…

csharp read excel file get sheetName list

1 /// <summary>2 /// 3 /// 塗聚文4 /// 201208035 /// Geovin Du6 ///找到EXCEL的工作表名称 要考慮打開的文件的進程問題7 /// </summary>8 /// <param name"filename">…

Spring Bean的生命周期以及IOC源码解析

IOC源码这一块太多只能讲个大概吧&#xff0c;建议还是去买本Spring IOC源码解析的书来看比较好&#xff0c;我也是自己看源代码以及视频整理的笔记 Bean的生命周期大概可以分为四个阶段&#xff0c;具体的等会再说&#xff0c;先看看IOC的源码吧 1、bean的创建 2、bean的属…

python3绘图_python3绘图示例2(基于matplotlib:柱状图、分布图、三角图等)

#!/usr/bin/env python# -*- coding:utf-8 -*-from matplotlib import pyplot as pltimport numpy as npimport pylabimport os,sys,time,math,random# 图1-给已有的图加上刻度filer‘D:\jmeter\jmeter3.2\data\Oracle数据库基础.png‘arrnp.array(file.getdata()).reshape(fil…

bzoj4152-[AMPPZ2014]The_Captain

Description 给定平面上的n个点&#xff0c;定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|)&#xff0c;求从1号点走到n号点的最小费用。 Input 第一行包含一个正整数n(2<n<200000)&#xff0c;表示点数。 接下来n行&#xff0c;每行包含两个整数x[i],yi&#xff0c;…

python日志统计_python试用-日志统计

最近两天尝试用python代替bash写Linux Shell脚本来统计日志。发现python写起来比bash更简单和容易阅读&#xff0c;发现不少惊喜。所以写了一个粗糙的脚本来统计日志。目标1、通过简单命令和脚本统计事件发生数2、日志限定文本类型假定环境日志文件&#xff1a;1.logtest:aaa,1…

Spring AOP两种使用方式以及如何使用解析

AOP是一种面向切面编程思想&#xff0c;也是面向对象设计&#xff08;OOP&#xff09;的一种延伸。 在Spring实现AOP有两种实现方式&#xff0c;一种是采用JDK动态代理实现&#xff0c;另外一种就是采用CGLIB代理实现&#xff0c;Spring是如何实现的在上篇已经讲到了Spring Be…

如何用python生成可执行程序必须经过_python怎么生成可执行文件

.py文件&#xff1a;对于开源项目或62616964757a686964616fe58685e5aeb931333363393664者源码没那么重要的&#xff0c;直接提供源码&#xff0c;需要使用者自行安装Python并且安装依赖的各种库。(Python官方的各种安装包就是这样做的).pyc文件&#xff1a;有些公司或个人因为机…

Jmeter 老司机带你一小时学会Jmeter

Jmeter的安装 官网下载地址&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 作为Java应用&#xff0c;是需要JDK环境的&#xff0c;因此需要下载安装JAVA&#xff0c;并且作必要的的环境变量配置。 一、bin目录 examples:    目录中有CSV样例 jmeter.bat/jmeter…

MongoDB位运算基本使用以及位运算应用场景

最近在公司业务上用到了二进制匹配数据&#xff0c;但是MongoDB进行二进制运算&#xff08;Bitwise&#xff09;没用过&#xff0c;网上博客文章少&#xff0c;所以就上官网看API&#xff0c;因此记录一下&#xff0c;顺便在普及一下使用二进制位运算的一些应用。 在MongoDB的…

好用的下拉第三方——nicespinner

1.简介 GitHub地址&#xff1a;https://github.com/arcadefire/nice-spinner Gradle中添加&#xff1a; allprojects {repositories {...maven { url "https://jitpack.io" }} }dependencies {implementation com.github.arcadefire:nice-spinner:1.3.7 }2.使用 xml文…

Mybatis配置文件参数定义

官网有时候进不去&#xff0c;所以就记录一下Mybatis的配置文件的各项参数定义&#xff0c;大家也可以上官网查询&#xff0c;官方文档&#xff0c;进不进的去看各自的缘分了 properties 定义配置&#xff0c;在这里配置的属性可以在整个配置文件使用&#xff1b;可以加载指定…