Several special ways of Spring Bean instantiation

Keywords: Java xml JDK encoding

  • ServiceLoader uses the reverse control in JDK
  • ServiceLoaderFactoryBean
  • AutowireCapableBeanFactory#createBean
  • BeanDefinitionRegistry#registerBeanDefinition

RumenzFactory interface and default implementation class DefaultRumenzFactory

RumenzFactory.java

package com.rumenz;

public interface RumenzFactory {
    //jdk1.8 default implementation
    default   RumenzA rumenzFactory(){
        RumenzA rumenzA = new RumenzA();
        rumenzA.setId("123");
        rumenzA.setName("Entry station");
        return rumenzA;
    }
    default  RumenzA rumenzFactory(String id){
        return new RumenzA(id);
    }
}

DefaultRumenzFactory.java

package com.rumenz;

public class DefaultRumenzFactory implements RumenzFactory{

}

ServiceLoader uses the reverse control in JDK

ServiceLoader.java


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

You need to create the META-INF/services / directory under the classpath, and create a file named factory interface in this directory (note that no suffix is required), and put the full class path of this interface in this file

└── resources
    ├── META-INF
    │   └── services
    │       └── com.rumenz.RumenzFactory
    ├── application.properties
    └── beans.xml
    
be careful: com.rumenz.RumenzFactory  It's a document
 The contents are factory interface:
com.rumenz.DefaultRumenzFactory

call 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());
        }
    }
}

output

RumenzA Nonparametric construction method
RumenzA{id='123', name='Entry station'}

ServiceLoaderFactoryBean

Generate a Bean for ServiceLoader

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>

call 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());
        }
    }

}

output

RumenzA Nonparametric construction method
RumenzA{id='123', name='Entry station'}

AutowireCapableBeanFactory#createBean

call 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());
    }
}

output

RumenzA Nonparametric construction method
RumenzA{id='123', name='Entry station'}

BeanDefinitionRegistry#registerBeanDefinition

call 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());

    }
}

Source code: https://github.com/mifunc/Spr...

Posted by svgmx5 on Tue, 30 Jun 2020 00:16:42 -0700