×

springboot注入bean的方式 pring

springboot注入bean的方式(springboot里面怎么获取bean)

admin admin 发表于2024-07-02 02:55:01 浏览11 评论0

抢沙发发表评论

大家好,关于springboot注入bean的方式很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于springboot里面怎么获取bean的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!

本文目录

springboot里面怎么获取bean

1 在Spring Boot可以扫描的包下假设我们编写的工具类为SpringUtil。如果我们编写的SpringUtil在Spring Boot可以扫描的包下或者使用@ComponentScan引入自定义的包了,那么原理很简单,只需要使得SpringUtil实现接口:ApplicationContextAware,然后加上@Component 注解即可,具体编码如下:com.kfit.base.util.SpringUtil:package com.kfit.base.util;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;/*** 普通类调用Spring bean对象:* 说明:* 1、此类需要放到App.java同包或者子包下才能被扫描,否则失效。* @author Administrator*/@Componentpublicclass SpringUtil implements ApplicationContextAware{privatestatic ApplicationContext applicationContext = null;@Overridepublicvoid setApplicationContext(ApplicationContext applicationContext) throwsBeansException {if(SpringUtil.applicationContext == null){SpringUtil.applicationContext = applicationContext;}System.out.println("---------------------------------------------------------------------");System.out.println("---------------------------------------------------------------------");System.out.println("---------------com.kfit.base.util.SpringUtil------------------------------------------------------");System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");System.out.println("---------------------------------------------------------------------");}//获取applicationContextpublicstatic ApplicationContext getApplicationContext() {returnapplicationContext;}//通过name获取 Bean.publicstatic Object getBean(String name){return getApplicationContext().getBean(name);}//通过class获取Bean.publicstatic 《T》 T getBean(Class《T》 clazz){return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublicstatic 《T》 T getBean(String name,Class《T》 clazz){return getApplicationContext().getBean(name, clazz);}}启动应用,查看控制台的打印信息是否有:======ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,2 不在Spring Boot的扫描包下方式一这种情况处理起来也很简单,先编写SpringUtil类,同样需要实现接口:ApplicationContextAware,具体编码如下:simple.plugin.spring.SpringUtilpackage simple.plugin.spring;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;publicclass SpringUtil implements ApplicationContextAware{privatestatic ApplicationContext applicationContext = null;@Overridepublicvoid setApplicationContext(ApplicationContext applicationContext) throwsBeansException {if(SpringUtil.applicationContext == null){SpringUtil.applicationContext = applicationContext;}System.out.println("---------------------------------------------------------------------");System.out.println("---------------------------------------------------------------------");System.out.println("---------------simple.plugin.spring.SpringUtil------------------------------------------------------");System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");System.out.println("---------------------------------------------------------------------");}//获取applicationContextpublicstatic ApplicationContext getApplicationContext() {returnapplicationContext;}//通过name获取 Bean.publicstatic Object getBean(String name){return getApplicationContext().getBean(name);}//通过class获取Bean.publicstatic 《T》 T getBean(Class《T》 clazz){return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublicstatic 《T》 T getBean(String name,Class《T》 clazz){return getApplicationContext().getBean(name, clazz);}}之后这一步才是关键,使用@Bean注解,在App.java类中将SpringUtil注解进来,代码如下:package com.kfit;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletComponentScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Import;import simple.plugin.spring.SpringUtil;/*** Hello world!**///其中@SpringBootApplication申明让spring boot自动给程序进行必要的配置,等价于以默认属性使用@Configuration,@EnableAutoConfiguration和@ComponentScan@SpringBootApplication@ServletComponentScanpublic class App {/**注册Spring Util* 这里为了和上一个冲突,所以方面名为:springUtil2* 实际中使用springUtil*/@Beanpublic SpringUtil springUtil2(){return new SpringUtil();}/***参数里VM参数设置为:-javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify* @param args*/public static void main(String args) {SpringApplication.run(App.class, args);}}3 不在Spring Boot的扫描包下方式二代码基本和上面都是相同的,主要是在App.java中使用@Import进行导入。而且在SpringUtil是不需要添加@Component注解@SpringBootApplication@ServletComponentScan@Import(value={SpringUtil.class})publicclass App {//省略其它代码.}说明以上3中方式都生效了,这3中方式根据实际情况选择一种方式就可以了。那么这样子在普通类既可以使用:SpringUtil.getBean() 获取到Spring IOC容器中的bean。当然也可以在Spring管理的类中使用:@Resouce或者@Autowired 进行注入使用,当然我们这个类的核心是普通类可以调用spring的bean进行使用了,是不是很神奇呢。

手动向Spring容器中注入对象

手动向Spring容器中注入对象的方法有很多,本文将简单阐述其中的四种 我们可以实现一个BeanFactory的后置处理器,在其中就可以获得BeanFactory,这样就可以调用registerSingleton方法。 注:此处bean的名字可以自定义,如这里就定义为sherlock。 如果在容器中获取该类 控制台输出: 对象就已成功注入到Spring容器中了。 注:其实在context中也有registerBean方法,可以实现一样的效果。(ApplicationContext其实继承了BeanFactory,所以它也拥有Bean工厂的功能,除此之外ApplicationContext还继承了很多其他的类,拥有一些辅助功能。总的来说,ApplicationContext其实包括了BeanFactory) 在配置类中,使用@Bean注解,返回一个想要注入的对象。@Bean括号中是bean的名字,默认为类名的小写形式。 控制台输出: ***隐藏网址*** 我们可以创建一个类去实现FactoryBean接口 控制台输出: @Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中 @Import的三种用法主要包括: 注意:这样注入的类名为类的全限定名。 @Import三种方式的总结 第一种用法:@Import({ 要导入的容器中的组件 } ):容器会自动注册这个组件,id默认是全类名 第二种用法:ImportSelector:返回需要导入的组件的全类名数组,springboot底层用的特别多。 第三种用法:ImportBeanDefinitionRegistrar:手动注册bean到容器 好了,以上就是四种手动向Spring容器中注入对象的方法。总结一下吧,分别是:

SpringBoot运行时动态注册Bean到IOC容器中

通过实现 ApplicationContextAware 接口,通过Spring启动过程中回调 setApplicationContext 接口,获取spring的IOC容器,然后就可以注册bean到Spring容器中了。

springboot 根据配置文件的不同,选择注入不同的bean

1.场景描述 业务系统中,配置文件不同,使用的业务逻辑也不同。我们可以使用模板方法模式把业务分成多个service。如下图 2.ConditionalOnProperty源码说明 3.如何使用 AbstractServiceImpl1-- 默认使用的方法 UserServiceImpl1-- UserServiceImpl2-- 使用时,直接注入service,会根据配置文件来选择哪个service生效 4.上面是针对一个配置项,如果有多个配置项,可以使用@ConditionalOnExpression,来根据表达式来选择使用哪个service ConditionalOnExpression 源码说明 使用起来也比较方便 @ConditionalOnExpression("!${sence.cascade.enable:false} && ${sence.cascade.test:0} == 2")

Spring Bean 的注册和注入的几种常用方式和区别

我们一般在项目开发中都是使用这种方式。 一般导入第三方组件的时候使用,如注册一个 RedisTemplate : 一般快速导入一批组件时使用,如同时注册好几个动物类: 容器中的Bean: 只有动物园里面有 猫和狗的时候我么才将猪注入进去。ImportBeanDefinitionRegistrar注册器,在注册bean的过程中会在最后执行。 输出结果: 以下是他们在实现依赖注入时执行顺序的概括: @Autowired and @Inject @Resource ***隐藏网址*** spring-boot-student-spring 工程 为监控而生的多级缓存框架 layering-cache 这是我开源的一个多级缓存框架的实现,如果有兴趣可以看一下

Spring 优雅注册 Bean 的方式

这篇先说明用法,下篇分析以下场景是如何将 Bean 注册进 IOC容器的。

这种用法在项目中是非常常见的,基本上是必有。我们来看下用法:

这样一个 Bean 就注册进 IOC 容器了,Bean 的名称默认是方法名,并且是不会转换大小写的,也就是假如你的方法名是 TestBean() ,那么 Bean 的名称就是 TestBean 。当然我们也可以使用 name 或者 value 指定 Bean 的名称,比如 @Bean(value = "testBean"),如果二者同时存在则会报错。

我们来看下其他属性:

autowireCandidate:默认值是 true 。如果设置为 false 的话,那么通过 byType 的方式获取 Bean 就会报错,当然我们可以使用 Resource 注解获取。

initMethod:在 Bean 实例化后调用的初始化方法,值是 Bean 类中的方法名。

destroyMethod:在 Bean 要销毁时调用的清理方法,值是 Bean 类中的方法名。

@Bean 注解只能定义在 @Configuration 类下吗? NO NO NO,它可以定义在任意能被 IOC 扫描的注解下,比如 @Component注解,至于区别,下篇再讲。

先讲普通用法:

深度用法:

ComponentScan 注解中有两个这样的属性:includeFilters 与 excludeFilters,前一个是只包含规则,后一个是排除包含规则,他们的值是一个 @Filter 注解的形式,Filter 中的 type 有 5 中类型,分别如下。

1、ANNOTATION

第一种是以注解的形式包含或不包含,比如:

这里边要配置useDefaultFilters = false 禁用默认规则,因为默认规则是扫描所有,配只包含就没用了。这里的意思只扫描 Configuration 注解。

2、ASSIGNABLE_TYPE

这种是包含我们给定的类型,不管是给定的类型和子类都会被包含进 IOC 容器。

然后我们发现 testBean 注册进去了,为什么我们不标注 @Component 这样的注解实例也会被注册进 IOC 呢?因为 ComponentScan 会扫描包下所有文件,只要符合我们定义的过滤规则,它就会将 Bean 注册进 IOC 容器中。

3、ASPECTJ

ASPECTJ 是使用 aspectj 表达式

4、REGEX

REGEX 是使用正则表达式

5、CUSTOM

这种呢就是我们 SpringBootApplication 注解用到的方式了,我来解释一下具体规则:这种方式是可以自己自定义扫描规则,它接受一个实现 TypeFilter 接口的类。

当它扫描类的时候扫描到了 TestBean,然后符合了我的匹配规则(也就是返回true)就注册进去了。

下面的例子中,我们直接看 Spring 源码的实现比较具有代表性一点。

我们点进 @EnableTransactionManagement 注解中,发现了这个 @Import(TransactionManagementConfigurationSelector.class),它的作用就是将类导入,类会被注册进 IOC 容器中。

这个注解放置的位置要是 Spring 能扫描到的地方,不然 Spring 也不会主动去解析这个注解。

如果我们自己要使用注解的话,我们可以做个类似于 EnableTransactionManagement 的功能插拔式导入配置类,这样就可以实现动态开启一些 Bean 了。

我们还是来看下 TransactionManagementConfigurationSelector 这个类,看下它的继承关系发现它间接性的实现了 ImportSelector 接口,主要看它实现的这个方法:

这个方法的作用就是根据你返回的类全限定名(org.springframework.context.annotation.AutoProxyRegistrar)数组来创建 Bean 。

实现了 ImportSelector 的类也是需要使用 @Import 导入。

这个我们来看下 @MapperScan (org.mybatis.spring.annotation)导入的 MapperScannerRegistrar 发现它实现了 ImportBeanDefinitionRegistrar:

它的作用是拿到 BeanDefinitionRegistry Bean 的定义信息,然后往里面加 BeanDefinition 就会将相应的对象注册进去,它更深入的就不说了,实际上就是解析下注解属性,然后扫描相应的包下的类注册 Bean。我们自己搞个简单的。

这样就注册了一个 Bean 名称是 testBean 类型是 TestBean 类型的 Bean 了。

如果注册的是一个有参构造器呢?那就这样:

addConstructorArgValue 根据构造器参数的顺序去添加。

实现了 ImportBeanDefinitionRegistrar 的类也是需要使用 @Import 导入。

然后 TestBean 就注册进去了,打印的时候我们发现 Bean 的名称是 MyFactoryBean 的全限定名,但是它的类型是 TestBean 类型的,如果想要获取 MyFactoryBean 类型的 Bean 的话,通过 Bean 名称为 &myFactoryBean 就能获取到。

在我们的Spring Boot项目中,一般都是只扫描主类下的所有类,然后将一些被特定注解标注的类加载到IOC容器,但是如果我们将包分离,我们又如何更加方便的将其他包的类加载进来呢? spring boot提供了一种类似于Java的SPI(服务发现)机制spring.factories,只要在resources目录下创建META-INF文件夹,再创建 spring.factories文件,然后再里面配置

这样在导入当前包的就会自动扫描spring.factories文件,解析后将里面的一些类加载到IOC容器中。具体的实现代码在spring-core的SpringFactoriesLoader类中。

这些就不讲了。

以上就是我们为大家找到的有关“springboot注入bean的方式(springboot里面怎么获取bean)”的所有内容了,希望可以帮助到你。如果对我们网站的其他内容感兴趣请持续关注本站。