Spring Bean实例化的几种特殊方式

  • ServiceLoader 利用JDK里面的反向控制
  • ServiceLoaderFactoryBean
  • AutowireCapableBeanFactory#createBean
  • BeanDefinitionRegistry#registerBeanDefinition

RumenzFactory接口和默认实现类DefaultRumenzFactory


RumenzFactory.java

package com.rumenz;

public interface RumenzFactory {
    //jdk1.8 默认实现
    default   RumenzA rumenzFactory(){
        RumenzA rumenzA = new RumenzA();
        rumenzA.setId("123");
        rumenzA.setName("入门小站");
        return rumenzA;
    }
    default  RumenzA rumenzFactory(String id){
        return new RumenzA(id);
    }
}

DefaultRumenzFactory.java

package com.rumenz;

public class DefaultRumenzFactory implements RumenzFactory{

}


ServiceLoader 利用JDK里面的反向控制

ServiceLoader.java


public final class ServiceLoader<S>
    implements Iterable<S>
{
    private static final String PREFIX = "META-INF/services/";
    //....
}

需要在classpath下创建META-INF/services/目录,在此目录下创建一个文件名为工厂接口的文件(注意不需要后缀),此文件里面放上此接口的全类路径

└── resources
    ├── META-INF
    │   └── services
    │       └── com.rumenz.RumenzFactory
    ├── application.properties
    └── beans.xml
    
注意:com.rumenz.RumenzFactory 是个文件
里面的内容为工厂接口:
com.rumenz.DefaultRumenzFactory

调用DemoApplication.java

package com.rumenz;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Iterator;
import java.util.ServiceLoader;

public class DemoApplication {
    public static  void main(String[] args) {
        ClassPathXmlApplicationContext  ca=new ClassPathXmlApplicationContext("beans.xml");
        ServiceLoader<RumenzFactory> serviceLoader= ServiceLoader.load(RumenzFactory.class,Thread.currentThread().getContextClassLoader());
        Iterator<RumenzFactory> iterator = serviceLoader.iterator();
        while(iterator.hasNext()){
            RumenzFactory next = iterator.next();
            System.out.println(next.rumenzFactory());
        }
    }
}

输出

RumenzA 无参构造方法
RumenzA{id='123', name='入门小站'}

ServiceLoaderFactoryBean

生成一个ServiceLoader的Bean

beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="instance-by-serviceLoaderFactoryBean" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
  <property name="serviceType" value="com.rumenz.RumenzFactory"></property>
</bean>
</beans>

调用DemoApplication.java

package com.rumenz;

public class DemoApplication {
    public static  void main(String[] args) {
        ClassPathXmlApplicationContext  ca=new ClassPathXmlApplicationContext("beans.xml");

        ServiceLoader bean = ca.getBean("instance-by-serviceLoaderFactoryBean", ServiceLoader.class);
        Iterator iterator = bean.iterator();
        while (iterator.hasNext()){
            RumenzFactory next = (RumenzFactory) iterator.next();
            System.out.println(next.rumenzFactory());
        }
    }

}

输出

RumenzA 无参构造方法
RumenzA{id='123', name='入门小站'}

AutowireCapableBeanFactory#createBean

调用DemoApplication.java

package com.rumenz;

public class DemoApplication {
    public static  void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
        AutowireCapableBeanFactory abf = ac.getAutowireCapableBeanFactory();
        DefaultRumenzFactory bean = abf.createBean(DefaultRumenzFactory.class);
        System.out.println(bean.rumenzFactory());
    }
}

输出

RumenzA 无参构造方法
RumenzA{id='123', name='入门小站'}

BeanDefinitionRegistry#registerBeanDefinition

调用DemoApplication.java

package com.rumenz;

public class DemoApplication {
    public static  void main(String[] args) {
         AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext();
        ac.register(DemoApplication.class);
        registerBean(ac,"rumenza");

        ac.refresh();
        RumenzA rumenza = (RumenzA) ac.getBean("rumenza");
        System.out.println(rumenza);
        ac.close();
    }
    public static void registerBean(BeanDefinitionRegistry reg,String beanName){
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RumenzA.class);
        reg.registerBeanDefinition(beanName,beanDefinitionBuilder.getBeanDefinition());

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0EABxVZs-1593446721149)(https://rumenz.com/static/cimg/20200628/1593359495.png ‘‘图片title’’)]

源码:https://github.com/mifunc/Spring-Bean-special-instantiate

原文: https://rumenz.com/rumenbiji/Spring-Bean-special-instantiate.html

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值