zoukankan      html  css  js  c++  java
  • spring-FactoryBean

    spring-FactoryBean

    FactoryBean 是一个将对象构造逻辑封装在一个类中的一种设计模式。它可以用于构造复杂的对象,因为可能有许多的依赖关系,或者构造逻辑本身高度依赖于配置时,可以使用.FactoryBean 可以用于帮助Spring 构造无法轻松构造的对象。

    我们先来看下这个模式的功能:

    public interface FactoryBean<T> {
    	/**
    	* 返回一个实例
    	*/
    	@Nullable
    	T getObject() throws Exception;
    
    	/**
    	* 返回即将创建的实例的类型
    	*/
    	@Nullable
    	Class<?> getObjectType();
    
    	/**
    	* 返回是否单例
    	*/
    	default boolean isSingleton() {
    		return true;
    	}
    
    }
    

    举个例子:

    首先有两个类 Person 和 Car ,Person 依赖 Car
    Person类:

    public class Person {
        private Car car;
    
        private void setCar(Car car) {
            this.car = car;
        }
    }
    

    Car类:

    public class Car {
    
    
    }
    
    

    Car 的 builder:

    public class CarBuilder {
    
    
        private String make;
        private int year;
    
    
        public String getMake() {
            return make;
        }
    
        public void setMake(String make) {
            this.make = make;
        }
    
        public int getYear() {
            return year;
        }
    
        public void setYear(int year) {
            this.year = year;
        }
    
        public static CarBuilder car() {
            return new CarBuilder();
        }
    
        public Car factory() {
            return new Car();
        }
    }
    

    然后有个 MyCarFactoryBean 实现 FactoryBean

    public class MyCarFactoryBean implements FactoryBean<Car> {
    
        private String make;
        private int year;
    
    
        public String getMake() {
            return make;
        }
    
        public void setMake(String make) {
            this.make = make;
        }
    
        public int getYear() {
            return year;
        }
    
        public void setYear(int year) {
            this.year = year;
        }
    
        @Override
        public Car getObject() throws Exception {
            // 如果你的构造逻辑很简单的话,其实没必要使用FactoryBean
            CarBuilder cb = CarBuilder.car();
    
            if (year != 0) {
                cb.setYear(this.year);
            }
    
            if (StringUtils.hasText(this.make)) {
                cb.setMake(this.make)
            }
            return cb.factory();
        }
    
        @Override
        public Class<?> getObjectType() {
            return Car.class;
        }
    
    }
    
    

    Bean 的配置:

    <bean class = "a.b.c.MyCarFactoryBean" id = "car">
    	<property name = "make" value ="Honda"/>
    	<property name = "year" value ="1984"/>
    </bean>
    <bean class = "a.b.c.Person" id = "josh">
    	<property name = "car" ref = "car"/>
    </bean>
    

    简单说明一下,这个功能是提供一个Person 类的bean,并依赖 Car 的bean,但是其中Car 的bean 是通过 MyCarFactoryBean 实现 FactoryBean 来的,因为我们可以在 MyCarFactoryBean 中自定义Car 的构建过程。在这个例子中,FactoryBean 的 getObject() 将会被spring 调用,而不是 FactoryBean 本身。如果你使用的是java 配置的方式,它需要你手动调用getObject()方法了,例如

    // 和 xml 模式配置功能一样			
    @Configuration 
    public class CarConfiguration { 
    
      @Bean 
      public MyCarFactoryBean carFactoryBean(){ 
    	MyCarFactoryBean cfb = new MyCarFactoryBean();
    	cfb.setMake("Honda");
    	cfb.setYear(1984);
    	return cfb;
      }
    
      @Bean
      public Person aPerson(){ 
    	Person person = new Person();
    	person.setCar( carFactoryBean().getObject());
    	return person; 
      }	
    }
    

    Spring FactoryBeans具有任何其他Spring bean的所有其他特性,包括Spring容器中所有Bean都享有的生命周期钩子和服务(如AOP)因此,如果您希望在设置FactoryBean上的属性之后执行构造逻辑,但在调用getObject()方法之前,则可以告诉Spring容器为FactoryBean提供回调。一种方法是实现InitializingBean接口。无论如何,这都会被调用。更多以POJO为中心的替代方法是使用@PostConstruct注释方法。在这种情况下,在设置了代码> make和year属性之后,将调用此方法。您可以使用此回调在对象构造完成之前进行完整性检查,但在容器的配置完成之后。

     @PostConstruct 
     public void setup() throws Throwable { 
       // these methods throw an exception that 
       // will arrest construction if the assertions aren't met
       Assert.notNull(this.make, "the 'make' must not be null")	;
       Assert.isTrue(this.year > 0, "the 'year' must be a valid value"); 
     }
    

    FactoryBean在XML配置中很有用,作为其局限性的解决方法。 它是在静态XML中注入“动作”的方法,但是在 java 配置方式中,显得就不是那么有用了。

    参考文档

    人的潜力是可以激发的,比如说你给我50斤的砖我可能拎不动,但你要是给我100斤的人民币我肯定拎起来就跑。
  • 相关阅读:
    用户访问过的产品,在cookie记录产品id,id取得产品信息
    文件上传操作
    上次文件先创建目录,再上传到目录里面去
    解决PHPcms 2008 sp4 注册选择模型关闭后,注册不能自动登录的问题
    php输出表格的方法
    php中实现退后功能,不用历史记录
    PHP的substr_replace将指定两位置之间的字符替换为*号
    php算开始时间到过期时间的相隔的天数,同理可以实现相隔年,小时,分,秒等数
    不用js用php做tab选项卡
    再也回不去的从前
  • 原文地址:https://www.cnblogs.com/mojiruo/p/11300150.html
Copyright © 2011-2022 走看看