网站开发留言板,怎么做购物优惠券网站,做网站 嵌入支付,c 做网站后端Spring 中有哪些方式可以把 Bean 注入到 IOC 容器#xff1f; 关于这个问题#xff0c;我的回答入下#xff1a;把 Bean 注入到 IOC 容器里面的方式有 7 种方式 1. 使用 xml 的方式来声明 Bean 的定义#xff0c;Spring 容器在启动的时候会加载并解析这 个 xml#xff0c;…Spring 中有哪些方式可以把 Bean 注入到 IOC 容器 关于这个问题我的回答入下把 Bean 注入到 IOC 容器里面的方式有 7 种方式 1. 使用 xml 的方式来声明 Bean 的定义Spring 容器在启动的时候会加载并解析这 个 xml把 bean 装载到 IOC 容器中。
例如
bean id name class property name value /property name ref /constructor-arg name value /
/beanspring会将装配好的bean存储在mapbeanName-bean对象中。
xml中的id对应map中的beanName必须是唯一的
xml中的name对应map中的bean对象的alias别名可以有多个通过逗号隔开也是唯一的。
可以通过beanName或者alias获取bean。
此处还可以通过bean类型获取bean如果该类型的bean存在多个则会报错。
ApplicationContext contextnew ClassPathXmlApplicationContext(“applicationContext.xml”); Music music(Music) context.getBean(Music.class); 可以不声明id和name如果这样默认id是【全类名#0】name(alias)默认是【全类名】假设再声明一个同样的bean则默认ID是全类名#1没有alias。
2.使用CompontScan 注解来扫描声明了Controller、Service、 Repository、Component 注解的类。
使用Configuration 注解声明配置类并使用Bean 注解实现 Bean 的定义
这种方式其实是 xml 配置方式的一种演变是 Spring 迈入到无配置化时代的里程
碑。
使用Import 注解导入配置类或者普通的 Bean。 //类中组件统一设置。满足当前条件这个类中配置的所有bean注册才能生效Conditional({WindowsCondition.class})ConfigurationImport({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})//Import导入组件id默认是组件的全类名public class MainConfig2 {//默认是单实例的/*** ConfigurableBeanFactory#SCOPE_PROTOTYPE * see ConfigurableBeanFactory#SCOPE_SINGLETON * see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request* see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion* return\* Scope:调整作用域* prototype多实例的ioc容器启动并不会去调用方法创建对象放在容器中。* 每次获取的时候才会调用方法创建对象* singleton单实例的默认值ioc容器启动会调用方法创建对象放到ioc容器中。* 以后每次获取就是直接从容器map.get()中拿* request同一次请求创建一个实例* session同一个session创建一个实例* * 懒加载* 单实例bean默认在容器启动的时候创建对象* 懒加载容器启动不创建对象。第一次使用(获取)Bean创建对象并初始化* */// Scope(prototype)LazyBean(person)public Person person(){System.out.println(给容器中添加Person....);return new Person(张三, 25);}/*** Conditional({Condition}) 按照一定的条件进行判断满足条件给容器中注册bean* * 如果系统是windows给容器中注册(bill)* 如果是linux系统给容器中注册(linus)*/Bean(bill)public Person person01(){return new Person(Bill Gates,62);}Conditional(LinuxCondition.class)Bean(linus)public Person person02(){return new Person(linus, 48);}/*** 给容器中注册组件* 1、包扫描组件标注注解Controller/Service/Repository/Component[自己写的类]* 2、Bean[导入的第三方包里面的组件]* 3、Import[快速给容器中导入一个组件]* 1、Import(要导入到容器中的组件)容器中就会自动注册这个组件id默认是全类名* 2、ImportSelector:返回需要导入的组件的全类名数组* 3、ImportBeanDefinitionRegistrar:手动注册bean到容器中* 4、使用Spring提供的 FactoryBean工厂Bean;* 1、默认获取到的是工厂bean调用getObject创建的对象* 2、要获取工厂Bean本身我们需要给id前面加一个* colorFactoryBean*/Beanpublic ColorFactoryBean colorFactoryBean(){return new ColorFactoryBean();}使用 FactoryBean 工厂 bean动态构建一个 Bean 实例Spring Cloud
OpenFeign 里面的动态代理实例就是使用 FactoryBean 来实现的。 / /创建一个Spring定义的FactoryBeanpublic class ColorFactoryBean implements FactoryBeanColor {//返回一个Color对象这个对象会添加到容器中Overridepublic Color getObject() throws Exception {// TODO Auto-generated method stubSystem.out.println(ColorFactoryBean...getObject...);return new Color();}Overridepublic Class? getObjectType() {// TODO Auto-generated method stubreturn Color.class;}//是单例//true这个bean是单实例在容器中保存一份0 //false多实例每次获取都会创建一个新的beanOverridepublic boolean isSingleton() {// TODO Auto-generated method stubreturn false;}}Springboot有大量的ConditionXXXX注解 public class LinuxCondition implements Condition {/*** ConditionContext判断条件能使用的上下文环境* AnnotatedTypeMetadata注释信息*/public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// TODO是否linux系统//1、能获取到ioc使用的beanfactoryConfigurableListableBeanFactory beanFactory context.getBeanFactory();//2、获取类加载器ClassLoader classLoader context.getClassLoader();//3、获取当前环境信息Environment environment context.getEnvironment();//4、获取到bean定义的注册类BeanDefinitionRegistry registry context.getRegistry();String property environment.getProperty(os.name);
//可以判断容器中的bean注册情况也可以给容器中注册beanboolean definition registry.containsBeanDefinition(person);if(property.contains(linux)){return true;}return false;}}实现 ImportBeanDefinitionRegistrar 接口可以动态注入 Bean 实例。这个在
Spring Boot 里面的启动注解有用到。
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** AnnotationMetadata当前类的注解信息* BeanDefinitionRegistry:BeanDefinition注册类* 把所有需要添加到容器中的bean调用* BeanDefinitionRegistry.registerBeanDefinition手工注册进来*/Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean definition registry.containsBeanDefinition(com.atguigu.bean.Red);boolean definition2 registry.containsBeanDefinition(com.atguigu.bean.Blue);if(definition definition2){//指定Bean定义信息Bean的类型Bean。。。RootBeanDefinition beanDefinition new RootBeanDefinition(RainBow.class);//注册一个Bean指定bean名registry.registerBeanDefinition(rainBow, beanDefinition);}}}实现 ImportSelector 接口动态批量注入配置类或者 Bean 对象这个在 SpringBoot 里面的自动装配机制里面有用到。 public class MyImportSelector implements ImportSelector {//返回值就是到导入到容器中的组件全类名//AnnotationMetadata:当前标注Import注解的类的所有注解信息public String[] selectImports(AnnotationMetadata importingClassMetadata) {// TODO Auto-generated method stub//importingClassMetadata//方法不要返回null值return new String[]{com.atguigu.bean.Blue,com.atguigu.bean.Yellow};}}获取Spring中bean的5种方式
获取Spring中的bean有很多种方式再次总结一下
第一种在初始化时保存ApplicationContext对象
ApplicationContext ac new FileSystemXmlApplicationContext(applicationContext.xml);
ac.getBean(beanId);说明这种方式适用于采用Spring框架的独立应用程序需要程序通过配置文件手工初始化Spring。
第二种通过Spring提供的工具类获取ApplicationContext对象
import org.springframework.web.context.support.WebApplicationContextUtils;
ApplicationContext ac1 WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ApplicationContext ac2 WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
ac1.getBean(beanId);
ac2.getBean(beanId);说明
1、这两种方式适合于采用Spring框架的B/S系统通过ServletContext对象获取ApplicationContext对象然后在通过它获取需要的类实例 2、第一种方式在获取失败时抛出异常第二种方式返回null。
第三种继承自抽象类ApplicationObjectSupport
说明通过抽象类ApplicationObjectSupport提供的getApplicationContext()方法可以方便的获取到ApplicationContext实例进而获取Spring容器中的bean。Spring初始化时会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。 第四种继承自抽象类WebApplicationObjectSupport
说明和上面方法类似通过调用getWebApplicationContext()获取WebApplicationContext实例
第五种实现接口ApplicationContextAware
说明实现该接口的setApplicationContext(ApplicationContext context)方法并保存ApplicationContext对象。Spring初始化时会通过该方法将ApplicationContext对象注入。
虽然Spring提供了后三种方法可以实现在普通的类中继承或实现相应的类或接口来获取Spring的ApplicationContext对象但是在使用时一定要注意继承或实现这些抽象类或接口的普通java类一定要在Spring的配置文件即application-context.xml文件中进行配置否则获取的ApplicationContext对象将为null。
下面通过实现接口ApplicationContextAware的方式演示如何获取Spring容器中的bean 首先自定义一个实现了ApplicationContextAware接口的类实现里面的方法
package com.ghj.tool;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;public class SpringConfigTool implements ApplicationContextAware {// extends ApplicationObjectSupport{private static ApplicationContext ac null;private static SpringConfigTool springConfigTool null;public synchronized static SpringConfigTool init() {if (springConfigTool null) {springConfigTool new SpringConfigTool();}return springConfigTool;}public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {ac applicationContext;}public synchronized static Object getBean(String beanName) {return ac.getBean(beanName);}
}
其次在applicationContext.xml文件进行配置
bean idSpringConfigTool classcom.ghj.tool.SpringConfigTool/最后通过如下代码就可以获取到Spring容器中相应的bean了
SpringConfigTool.getBean(beanId);注意一点在服务器启动Spring容器初始化时不能通过以下方法获取Spring容器:
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext; WebApplicationContext wac ContextLoader.getCurrentWebApplicationContext();
wac.getBean(beanID);