zoukankan      html  css  js  c++  java
  • Spring Bean

    Spring Bean

    构建示例

    User
    @Data
    public class User {
        private String name;
        private Integer age;
    }
    
    import com.fly.demo.User;
    import org.springframework.beans.MutablePropertyValues;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.support.AbstractBeanDefinition;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.GenericBeanDefinition;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import java.util.Map;
    
    /**
     * 构建示例:
     * 1.通过 BeanDefinitionBuilder 构建
     * 2.通过 AbstractBeanDefinition {@link AbstractBeanDefinition}以及派生类
     */
    public class BeanDefinitionCreationDemo {
        public static void main(String... args) {
            // 1.通过 BeanDefinitionBuilder 构建
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
            beanDefinitionBuilder
                    .addPropertyValue("name", "fly")
                    .addPropertyValue("age", 12);
            BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
    
            // 2.通过 AbstractBeanDefinition 以及派生类
            GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
            // 设置 Bean 类型
            genericBeanDefinition.setBeanClass(User.class);
            MutablePropertyValues propertyValues = new MutablePropertyValues();
            propertyValues
                    .add("name", "fly2")
                    .add("age", 13);
            genericBeanDefinition.setPropertyValues(propertyValues);
    
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            // 注册
            applicationContext.registerBeanDefinition("user", beanDefinition);
            applicationContext.registerBeanDefinition("user2", genericBeanDefinition);
            // 启动 Spring 应用上下文
            applicationContext.refresh();
            // 获取bean
            Map<String, User> stringUserMap = applicationContext.getBeansOfType(User.class);
            System.out.println(stringUserMap); // {user=User{name='fly', age=12}, user2=User{name='fly2', age=13}}
            // 显示地关闭 Spring 应用上下文
            applicationContext.close();
        }
    }
    

    Bean 别名示例

    
    /**
     * Bean 别名示例
     */
    public class BeanAliasDemo {
    
        public static void main(String... args) {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            applicationContext.register(BeanAliasDemo.class);
            applicationContext.refresh();
            User user = applicationContext.getBean("user", User.class);
            User flyUser = applicationContext.getBean("fly-user", User.class);
            System.out.println(user);
            System.out.println("fly-user 是否与 user Bean 相同:" + (user == flyUser));
            applicationContext.close();
        }
    
        @Bean(name = {"user", "fly-user"})
        public User user() {
            User user = new User();
            user.setName("fly");
            user.setAge(12);
            return user;
        }
    }
    

    注解 BeanDefinition 示例

    import com.fly.demo.User;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Import;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    /**
     * 注解 BeanDefinition 示例
     */
    @Import(AnnotationBeanDefinitionDemo.Config.class)
    public class AnnotationBeanDefinitionDemo {
        public static void main(String... args) {
            // 创建 BeanFactory 容器
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            // 注册 Configuration Class(配置类)
            applicationContext.register(AnnotationBeanDefinitionDemo.class);
    
            // 通过 BeanDefinition 注册 API 实现
            // 1.命名 Bean 的注册方式
            registerUserBeanDefinition(applicationContext, "fly-user");
            // 2. 非命名 Bean 的注册方法
            registerUserBeanDefinition(applicationContext, null);
    
            // 启动 Spring 应用上下文
            applicationContext.refresh();
            // 按照类型依赖查找
            System.out.println("Config 类型的所有 Beans" + applicationContext.getBeansOfType(Config.class));
            System.out.println("User 类型的所有 Beans" + applicationContext.getBeansOfType(User.class));
            // 显示地关闭 Spring 应用上下文
            applicationContext.close();
        }
    
        private static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
            beanDefinitionBuilder.addPropertyValue("name", "fly")
                    .addPropertyValue("age", 12);
            if (StringUtils.hasText(beanName)) {
                registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
            } else {
                // 非命名 Bean 注册方法
                BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
            }
        }
    
    //    @Component
        public static class Config {
            @Bean
            public User user() {
                return new User();
            }
        }
    
        @Bean
        public User user() {
            return new User();
        }
    }
    

    单体 Bean 注册实例

    
    import com.fly.demo.User;
    import org.springframework.beans.factory.config.SingletonBeanRegistry;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.support.AbstractApplicationContext;
    
    /**
     * 单体 Bean 注册实例
     * SingletonBeanRegistry#registerSingleton
     */
    public class SingletonBeanRegistrationDemo {
        public static void main(String... args) {
            // 创建 BeanFactory 容器
            AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            User user = new User();
            SingletonBeanRegistry singletonBeanRegistry = applicationContext.getBeanFactory();
            // 注册外部单例对象
            singletonBeanRegistry.registerSingleton("user", user);
            // 启动 Spring 应用上下文
            applicationContext.refresh();
    
            // 通过依赖查找的方式来获取 user
            User userByLookup = applicationContext.getBean("user", User.class);
            System.out.println("user == userByLookup : " + (user == userByLookup));
    
            // 关闭 Spring 应用上下文
            applicationContext.close();
        }
    }
    

    实例化 Spring Bean

    Bean 实例化(Instantiation)

    • 常规方式
      • 通过构造器(配置元信息:XML、Java 注解和 Java API )
      • 通过静态工厂方法(配置元信息:XML 和 Java API )
      • 通过 Bean 工厂方法(配置元信息:XML和 Java API )
      • 通过 FactoryBean(配置元信息:XML、Java 注解和 Java API )
    • 特殊方式
      • 通过 ServiceLoaderFactoryBean(配置元信息:XML、Java 注解和 Java API )
      • 通过 AutowireCapableBeanFactory#createBean(java.lang.Class, int, boolean)
      • 通过 BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
    META-INF/bean-instantiation-context.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 -->
        <bean id="user-by-static-method" class="com.fly.demo.User" factory-method="createUser"/>
    
        <!-- 实例(Bean)方法实例化 Bean -->
        <bean id="user-by-instance-method" factory-bean="userFactory" factory-method="createUser"/>
        <bean id="userFactory" class="com.fly.demo.DefaultUserFactory"/>
    
        <!-- FactoryBean实例化 Bean -->
        <bean id="user-by-factory-bean" class="com.fly.demo.UserFactoryBean"/>
    </beans>
    
    User
    @Data
    public class User {
        private String name;
        private Integer age;
    
        public static User createUser() {
            User user = new User();
            user.setName("default");
            user.setAge(0);
            return user;
        }
    }
    
    UserFactory
    /**
     * 工厂类
     */
    public interface UserFactory {
        default User createUser() {
            return User.createUser();
        }
    }
    
    DefaultUserFactory
    public class DefaultUserFactory implements UserFactory {
    
    }
    
    UserFactoryBean
    import org.springframework.beans.factory.FactoryBean;
    
    public class UserFactoryBean implements FactoryBean {
        @Override
        public User getObject() throws Exception {
            return User.createUser();
        }
    
        @Override
        public Class<?> getObjectType() {
            return User.class;
        }
    }
    
    Bean 实例化示例
    import com.fly.demo.User;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.Map;
    
    /**
     * Bean 实例化示例
     */
    public class BeanInstantiationDemo {
        public static void main(String...args){
            String location = "classpath:/META-INF/bean-instantiation-context.xml";
            AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(location);
            Map<String, User> userMap = applicationContext.getBeansOfType(User.class);
            System.out.println(userMap);
        }
    }
    

    ServiceLoader

    META-INF/services/com.fly.demo.UserFactory
    # com.fly.demo.DefaultUserFactory 的 接口实现
    com.fly.demo.DefaultUserFactory
    
    import com.fly.demo.UserFactory;
    
    import java.util.ServiceLoader;
    
    
    /**
     * META-INF/services/接口className
     * 内容为接口的实现类className
     */
    public class ServiceLoaderDemo {
        public static void main(String... args) {
            ServiceLoader<UserFactory> serviceLoader =
                    ServiceLoader.load(UserFactory.class, ServiceLoaderDemo.class.getClassLoader());
            for (UserFactory userFactory : serviceLoader) {
                System.out.println(userFactory.createUser());
            }
        }
    }
    
    特殊的 Bean 实例化示例
    META-INF/special-bean-instantiation-context.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="userFactoryServiceLoader"
              class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
            <property name="serviceType" value="com.fly.demo.UserFactory"/>
        </bean>
    </beans>
    
    import com.fly.demo.DefaultUserFactory;
    import com.fly.demo.UserFactory;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.ServiceLoader;
    
    /**
     * 特殊的 Bean 实例化示例
     */
    public class SpecialBeanInstantiationDemo {
        public static void main(String...args){
            AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/special-bean-instantiation-context.xml");
            ServiceLoader<UserFactory> serviceLoader = applicationContext.getBean("userFactoryServiceLoader", ServiceLoader.class);
            for (UserFactory userFactory : serviceLoader) {
                System.out.println(userFactory.createUser());
            }
    
            // 通过 AutowireCapableBeanFactory 创建
            AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
            UserFactory userFactory = autowireCapableBeanFactory.createBean(DefaultUserFactory.class);
            System.out.println(userFactory.createUser());
        }
    }
    

    初始化 Spring Bean

    Bean 初始化(Initialization)

    • @PostConstruct 标注方法
    • 实现 InitializingBean 接口的 afterPropertiesSet() 方法
    • 自定义初始化方法
      • XML 配置:<bean init-method=”init” ... />
      • Java 注解:@Bean(initMethod=”init”)
      • Java API:AbstractBeanDefinition#setInitMethodName(String)

    延迟初始化 Spring Bean

    Bean 延迟初始化(Lazy Initialization)

    • XML 配置:<bean lazy-init=”true” ... />
    • Java 注解:@Lazy(true)

    销毁 Spring Bean

    Bean 销毁(Destroy)

    • @PreDestroy 标注方法
    • 实现 DisposableBean 接口的 destroy() 方法
    • 自定义销毁方法
      • XML 配置:<bean destroy=”destroy” ... />
      • Java 注解:@Bean(destroy=”destroy”)
      • Java API:AbstractBeanDefinition#setDestroyMethodName(String)
    import com.fly.demo.UserFactory;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    public class FlyUserFactory implements UserFactory, InitializingBean, DisposableBean {
        @PostConstruct
        public void init() {
            System.out.println("@PostConstruct : UserFactory 初始化中...");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("InitializingBean#afterPropertiesSet() : UserFactory 初始化中...");
        }
    
        public void initUserFactory() {
            System.out.println("自定义初始化方法 initUserFactory() : UserFactory 初始化中...");
        }
    
    
        @PreDestroy
        public void preDestroy() {
            System.out.println("@PreDestroy : UserFactory 销毁中...");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("DisposableBean#destroy() : UserFactory 销毁中...");
        }
    
        public void doDestroy() {
            System.out.println("自定义销毁方法 doDestroy() : UserFactory 销毁中...");
        }
    
        @Override
        protected void finalize() throws Throwable {
            System.out.println("当前 DefaultUserFactory 对象正在被垃圾回收...");
        }
    }
    
    
    import com.fly.demo.UserFactory;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Lazy;
    
    public class BeanInitializationDemo {
        public static void main(String... args) {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            applicationContext.register(BeanInitializationDemo.class);
            applicationContext.refresh();
            System.out.println("Spring 应用上下文已启动...");
            UserFactory userFactory = applicationContext.getBean(UserFactory.class);
            System.out.println(userFactory.createUser());
            System.out.println("Spring 应用上下文准备关闭...");
            // 关闭 Spring 应用上下文
            applicationContext.close();
            System.out.println("Spring 应用上下文已关闭...");
            //@PostConstruct : UserFactory 初始化中...
            //InitializingBean#afterPropertiesSet() : UserFactory 初始化中...
            //自定义初始化方法 initUserFactory() : UserFactory 初始化中...
            //Spring 应用上下文已启动...
            //User(name=default, age=0)
            //Spring 应用上下文准备关闭...
            //@PreDestroy : UserFactory 销毁中...
            //DisposableBean#destroy() : UserFactory 销毁中...
            //自定义销毁方法 doDestroy() : UserFactory 销毁中...
            //Spring 应用上下文已关闭...
            //
            //Process finished with exit code 0
    
            // ---------------------------------------------------------------
            // lazy 延迟初始化 ,getBean才会初始化
    
            //Spring 应用上下文已启动...
            //@PostConstruct : UserFactory 初始化中...
            //InitializingBean#afterPropertiesSet() : UserFactory 初始化中...
            //自定义初始化方法 initUserFactory() : UserFactory 初始化中...
            //User(name=default, age=0)
            //Spring 应用上下文准备关闭...
            //@PreDestroy : UserFactory 销毁中...
            //DisposableBean#destroy() : UserFactory 销毁中...
            //自定义销毁方法 doDestroy() : UserFactory 销毁中...
            //Spring 应用上下文已关闭...
        }
    
        @Bean(initMethod = "initUserFactory", destroyMethod = "doDestroy")
        @Lazy
        public UserFactory userFactory(){
            return new FlyUserFactory();
        }
    }
    
    

    垃圾回收 Spring Bean

    Bean 垃圾回收(GC)

    1. 关闭 Spring 容器(应用上下文)
    2. 执行GC
    3. Spring Bean 覆盖的 finalize() 方法被回调
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * Bean 垃圾回收(GC)示例
     */
    public class BeanGarbageCollectionDemo {
        public static void main(String...args) throws InterruptedException {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
            // 注册 Configuration Class(配置类)
            applicationContext.register(BeanInitializationDemo.class);
            applicationContext.refresh();
            // 关闭 Spring 应用上下文
            applicationContext.close();
            Thread.sleep(5000L);
            // 强制触发 GC
            System.gc();
            Thread.sleep(5000L);
        }
    }
    
  • 相关阅读:
    Java Thread 总结
    用 for/in 在 Java 5.0 中增强循环
    JAVA中synchronized和lock详解
    centos vim的安装目录在哪里
    Cannot add task 'wrapper' as a task with that name already exists.
    servlet的生命周期
    I/O同个文件需要注意的问题
    分治策略---求最大子数组
    Java实现 100!的阶乘
    Java中方法的重载与覆盖(随笔01)
  • 原文地址:https://www.cnblogs.com/fly-book/p/13781758.html
Copyright © 2011-2022 走看看