Spring再次学习(3)

时隔一年多,在掌握了Spring、SpringBoot、SpringCloud之后

我再次回头,重新学习Spring框架

@Import注解:

快速导入组件,ID默认是组件全面,简单的使用:

public class Demo {
}
@Configuration
@Import({Demo.class})
public class MainConfig {
......
}

测试类:打印所有Bean

public class IOCTest {
    @Test
    public void test() {
        printBeans();
    }

    private void printBeans() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println(name);
        }
    }
}

ImportSelector选择器:在SpringBoot底层中有应用

@Configuration
@Import({MyImportSelector.class})
public class MainConfig {
}
package org.dreamtech.condition;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelector implements ImportSelector {
    /**
     * 重写
     * @param annotationMetadata 标注@Import类其他的注解
     * @return 注册对象
     */
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"org.dreamtech.bean.Demo","org.dreamtech.bean.Person"};
    }
}

打印发现Demo和Person被成功注册

ImportBeanDefinitionRegistrar:

@Configuration
@Import({MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}
package org.dreamtech.condition;

import org.dreamtech.bean.Demo;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * 注册
     *
     * @param annotationMetadata     当前类所有注解信息
     * @param beanDefinitionRegistry 注册类
     */
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        boolean definition = beanDefinitionRegistry.containsBeanDefinition("org.dreamtech.bean.Demo");
        //容器中如果有org.dreamtech.bean.Demo,那么就手动注册一个MyDemo
        if (definition) {
            BeanDefinition beanDefinition = new RootBeanDefinition(Demo.class);
            beanDefinitionRegistry.registerBeanDefinition("MyDemo", beanDefinition);
        }
    }
}

测试后打印如下:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
org.dreamtech.bean.Demo
org.dreamtech.bean.Person
MyDemo

最后一种给容器注册Bean的方式:

FactoryBean:Spring与其他框架整合大量使用到

package org.dreamtech.bean;

import org.springframework.beans.factory.FactoryBean;

public class DemoFactoryBean implements FactoryBean<Demo> {
    /**
     * Demo对象
     *
     * @return 返回一个对象,将它加入容器
     * @throws Exception 异常
     */
    public Demo getObject() throws Exception {
        System.out.println("创建Demo对象......");
        return new Demo();
    }

    /**
     * 获取类型
     *
     * @return Class
     */
    public Class<?> getObjectType() {
        return Demo.class;
    }

    /**
     * 是否是单例
     * true:单实例
     * false:多实例
     *
     * @return boolean
     */
    public boolean isSingleton() {
        return true;
    }
}
package org.dreamtech.config;

import org.dreamtech.bean.DemoFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类
 */
@Configuration
public class MainConfig {
    @Bean
    public DemoFactoryBean demoFactoryBean(){
        return new DemoFactoryBean();
    }
}

装配的Bean是DemoFactoryBean,那么容器中的Bean是它吗?

package org.dreamtech.test;

import org.dreamtech.config.MainConfig;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class IOCTest {

    private static AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

    @Test
    public void test() {
        printBeans();
        Object bean=getBeanByName("demoFactoryBean");
        System.out.println(bean.getClass());
    }

    private void printBeans() {
        String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println(name);
        }
    }

    private Object getBeanByName(String name) {
        return applicationContext.getBean(name);
    }
}

打印:发现虽然有一个Bean名称是demoFactoryBean,但它是Demo类型的

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
demoFactoryBean
创建Demo对象......
class org.dreamtech.bean.Demo

修改成多例模式:

    public boolean isSingleton() {
        return false;
    }
    @Test
    public void test() {
        printBeans();
        Object bean1=getBeanByName("demoFactoryBean");
        Object bean2=getBeanByName("demoFactoryBean");
        System.out.println(bean1==bean2);
    }

打印:每次获取都活调用getObject

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
demoFactoryBean
创建Demo对象......
创建Demo对象......
false

如果我强行想注册DemoFactoryBean本身呢?

查看BeanFactory源码这一部分:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
}

然后尝试着加入&前缀:

    @Test
    public void test() {
        printBeans();
        Object bean = getBeanByName("&demoFactoryBean");
        System.out.println(bean.getClass());
    }

打印如下:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
demoFactoryBean
class org.dreamtech.bean.DemoFactoryBean

猜你喜欢

转载自www.cnblogs.com/xuyiqing/p/11301701.html
今日推荐