Spring Bean的注入方式 & 在代码中获取bean的方式

Spring Bean的注入方式

依赖注入是一个让对象只通过构造参数,工厂方法的参数或者配置的属性来定义他们的依赖的过程。

依赖注入主要使用以下几种方式:

1. 基于构造函数的注入

基于构造函数的依赖注入是由IoC容器来调用类的构造函数,构造函数的参数代表这个Bean所
依赖的对象。

Spring Bean的注入方式 & 在代码中获取bean的方式_第1张图片

在上面代码这种情况下,容器可以通过使用构造函数参数的 type 属性来实现简单类型的匹配。


或者使用 index 属性来指定构造参数的位置。


2. Setter方式注入

基于Setter函数的依赖注入则是容器会调用Bean的无参构造函数,或者无参数的工厂方法,然后再来调用Setter方法来实现的依赖注入。

Spring Bean的注入方式 & 在代码中获取bean的方式_第2张图片
Spring Bean的注入方式 & 在代码中获取bean的方式_第3张图片

3. 工厂注入

静态工厂:无需创建工厂类实例就可以进行注入

Spring Bean的注入方式 & 在代码中获取bean的方式_第4张图片

Spring Bean的注入方式 & 在代码中获取bean的方式_第5张图片

实例工厂

public class CarFactory{  
    public Car createHongQiCar(){  
        Car car=new Car();  
        car.setBrand("红旗CA72");  
        return car;  
    }  
}  
  
  
 
4.注解注入

基于注解的组件(比如使用 @Component , @Controller 等)或者在配置了 @Configuration 的类上面使用 @Bean 的方法


总结:

通常比较好的方式是通过构造函数注入必要的依赖通过Setter方式来注入一些可选的依赖。其中,在Setter方法上面的 @Required 注解可用来构造必要的依赖。Spring推荐基于构造函数的注入,因为这种方式会促使开发者将组件开发成不可变对象而且确保了注入的依赖不为 null 。而且,基于构造函数的注入的组件被客户端调用的时候也是完全构造好的。当然,从另一方面来说,过多的构造函数参数也是非常差的代码方式,这种方式说明类貌似有了太多的功能,最好重构将不同职能分离。 基于Setter的注入只是用于可选的依赖,但是也最好配置一些合理的默认值。否则,需要对代码的依赖进行非NULL的检查。基于Setter方法的注入有一个便利之处在于这种方式的注入是可以进行重配置和重新注入的。 依赖注入的两种风格适合大多数的情况,但是有时使用第三方的库的时候,开发者可能并没有源码,而第三方的代码也没有setter方法,那么就只能使用基于构造函数的依赖注入。


Spring在代码中获取bean的几种方式

方法一:在初始化时保存ApplicationContext对象 方法二:通过Spring提供的utils类获取ApplicationContext对象 方法三:继承自抽象类ApplicationObjectSupport 方法四:继承自抽象类WebApplicationObjectSupport 方法五:实现接口ApplicationContextAware 方法六:通过Spring提供的ContextLoader

获取spring中bean的方式总结:

方法一:在初始化时保存ApplicationContext对象

[html]  view plain  copy
  1. ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");   
  2. ac.getBean("beanId");  

说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况。

方法二:通过Spring提供的工具类获取ApplicationContext对象
[java]  view plain  copy
  1. ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);   
  2. ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);   
  3. ac1.getBean("beanId");   
  4. ac2.getBean("beanId");  

说明:这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。上面两个工具方式的区别是,前者在获取失败时抛出异常,后者返回null。

方法三:继承自抽象类ApplicationObjectSupport

说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取ApplicationContext。

Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。

方法四:继承自抽象类WebApplicationObjectSupport

说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext

方法五:实现接口ApplicationContextAware

说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。Spring初始化时,会通过该方法将ApplicationContext对象注入。

以下是实现ApplicationContextAware接口方式的代码,前面两种方法类似:

[java]  view plain  copy
  1. package com.ifaboo.MiomOmmg.util;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.ApplicationContextAware;  
  5.   
  6. public class SpringContextUtil implements ApplicationContextAware {  
  7.     private static ApplicationContext applicationContext;  
  8.   
  9.     /** 
  10.      * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量. 
  11.      */  
  12.     public void setApplicationContext(ApplicationContext applicationContext) {  
  13.         SpringContextUtil.applicationContext = applicationContext; // NOSONAR  
  14.     }  
  15.   
  16.     /** 
  17.      * 取得存储在静态变量中的ApplicationContext. 
  18.      */  
  19.     public static ApplicationContext getApplicationContext() {  
  20.         checkApplicationContext();  
  21.         return applicationContext;  
  22.     }  
  23.   
  24.     /** 
  25.      * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 
  26.      */  
  27.     @SuppressWarnings("unchecked")  
  28.     public static  T getBean(String name) {  
  29.         checkApplicationContext();  
  30.         return (T) applicationContext.getBean(name);  
  31.     }  
  32.   
  33.     /** 
  34.      * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 
  35.      */  
  36.     @SuppressWarnings("unchecked")  
  37.     public static  T getBean(Class clazz) {  
  38.         checkApplicationContext();  
  39.         return (T) applicationContext.getBeansOfType(clazz);  
  40.     }  
  41.   
  42.     /** 
  43.      * 清除applicationContext静态变量. 
  44.      */  
  45.     public static void cleanApplicationContext() {  
  46.         applicationContext = null;  
  47.     }  
  48.   
  49.     private static void checkApplicationContext() {  
  50.         if (applicationContext == null) {  
  51.             throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");  
  52.         }  
  53.     }  
  54.   
  55. }  

虽然,spring提供的后三种方法可以实现在普通的类中继承或实现相应的类或接口来获取spring 的ApplicationContext对象,但是在使用是一定要注意实现了这些类或接口的普通java类一定要在Spring 的配置文件applicationContext.xml文件中进行配置。否则获取的ApplicationContext对象将为null。

方法六:通过Spring提供的ContextLoader
[java]  view plain  copy
  1. WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();  
  2. wac.getBean(beanID);  


最后提供一种不依赖于servlet,不需要注入的方式。但是需要注意一点,在服务器启动时,Spring容器初始化时,不能通过以下方法获取Spring 容器,细节可以查看spring源码org.springframework.web.context.ContextLoader。

转载自:Spring在代码中获取bean的几种方式

你可能感兴趣的:(Spring)