@ComponentScan+ @Controller + @Service + @Repositoryjava
导入第三方包里的组件spring
几个实体类的声明:shell
package com.niewj.bean; public class PojoBean { public PojoBean() { System.out.println("PojoBean[无注解java类] 初始化~~~"); } }
package com.niewj.bean; public class PojoBean2 { public PojoBean2(){ System.out.println("PojoBean2[无注解java类] 初始化~~~"); } }
package com.niewj.bean; public class PojoBean3 { public PojoBean3(){ System.out.println("PojoBean3[无注解java类] 初始化~~~"); } }
package com.niewj.bean; public class Pojo4 { public Pojo4(){ System.out.println("Pojo4[无注解java类] 初始化~~~"); } }
package com.niewj.bean; public class Pojo5 { public Pojo5(){ System.out.println("Pojo5[无注解java类] 初始化~~~"); } }
package com.niewj.config; import com.niewj.bean.PojoBean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration @Import(PojoBean.class) // 这里 public class ImportTestConfig { }
private AnnotationConfigApplicationContext printAnnoBeans(Class clazz) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(clazz); Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println); return ctx; } @Test public void testImport(){ // PojoBean*.java并没有注解类, 可是会初始化纳入spring容器管理! -> @Import的做用! ApplicationContext ctx = printAnnoBeans(ImportTestConfig.class); }
output:数组
PojoBean[无注解java类] 初始化~~~ org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory importTestConfig com.niewj.bean.PojoBean
能够看到 PojoBean 的初始化和bean id的展现!springboot
普通Javabean并无任何注解的:ide
package com.niewj.config; import com.niewj.bean.PojoBean; import com.niewj.bean.PojoBean2; import com.niewj.bean.PojoBean3; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration //@Import(PojoBean.class) @Import({PojoBean.class, PojoBean2.class, PojoBean3.class}) // 这里 public class ImportTestConfig { }
测试:测试
private AnnotationConfigApplicationContext printAnnoBeans(Class clazz) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(clazz); Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println); return ctx; } @Test public void testImport(){ // PojoBean*.java并没有注解类, 可是会初始化纳入spring容器管理! -> @Import的做用! ApplicationContext ctx = printAnnoBeans(ImportTestConfig.class); }
output: 能够看到这三个无注解的普通bean也被容器管理和初始化了!code
PojoBean[无注解java类] 初始化~~~ PojoBean2[无注解java类] 初始化~~~ PojoBean3[无注解java类] 初始化~~~ org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory importTestConfig com.niewj.bean.PojoBean com.niewj.bean.PojoBean2 com.niewj.bean.PojoBean3
@ImportSelector接口的实现类, 能够放入@Import中使用:对象
@Import是列出全部; @ImportSelector是返回一个 class name的字符串的数组, 能够理解为@Import的简化版(方便使用)接口
package com.niewj.config; import com.niewj.bean.PojoBean; import com.niewj.bean.PojoBean2; import com.niewj.bean.PojoBean3; import com.niewj.condition.MyImportSelector; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration //@Import(PojoBean.class) //@Import({PojoBean.class, PojoBean2.class, PojoBean3.class}) @Import({PojoBean.class, PojoBean2.class, PojoBean3.class, MyImportSelector.class}) // 这里 public class ImportTestConfig { }
MyImportSelector:
package com.niewj.condition; import com.niewj.bean.Pojo4; import com.niewj.bean.Pojo5; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; import java.util.ArrayList; import java.util.List; public class MyImportSelector implements ImportSelector { /** * 返回的数组中的类名, 也会做为加入容器管理的bean * @param importingClassMetadata 能够获取到当前类的全部注解信息! * @return */ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { List<String> classNameList = new ArrayList<>(); // 能够假设Pojo4/Pojo5的类名都读取字配置文件, 好比 spring.factories-->相似springboot源码 classNameList.add(Pojo4.class.getName()); classNameList.add(Pojo5.class.getName()); return classNameList.toArray(new String[0]); } }
testcase:
private AnnotationConfigApplicationContext printAnnoBeans(Class clazz) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(clazz); Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println); return ctx; } @Test public void testImport(){ // PojoBean*.java并没有注解类, 可是会初始化纳入spring容器管理! -> @Import的做用! ApplicationContext ctx = printAnnoBeans(ImportTestConfig.class); }
output: 可见: PojoBean/PojoBean2/PojoBean3都初始化了; 并且 ImportSelector中加入数组的 Pojo4/Pojo5也初始化了!
PojoBean[无注解java类] 初始化~~~ PojoBean2[无注解java类] 初始化~~~ PojoBean3[无注解java类] 初始化~~~ Pojo4[无注解java类] 初始化~~~ Pojo5[无注解java类] 初始化~~~ org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory importTestConfig com.niewj.bean.PojoBean com.niewj.bean.PojoBean2 com.niewj.bean.PojoBean3 com.niewj.bean.Pojo4 com.niewj.bean.Pojo5
能够结合已有beanDefinition信息!
package com.niewj.config; import com.niewj.bean.PojoBean; import com.niewj.bean.PojoBean2; import com.niewj.bean.PojoBean3; import com.niewj.condition.MyImportBeanDefRegistrar; import com.niewj.condition.MyImportSelector; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration //@Import(PojoBean.class) //@Import({PojoBean.class, PojoBean2.class, PojoBean3.class}) @Import({PojoBean.class, PojoBean2.class, PojoBean3.class, MyImportSelector.class, MyImportBeanDefRegistrar.class}) public class ImportTestConfig { }
MyImportBeanDefRegistrar:
package com.niewj.condition; import com.niewj.bean.Pojo4; import com.niewj.bean.Pojo5; import com.niewj.bean.PojoWhenHasPojo4AndPojo5; 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 MyImportBeanDefRegistrar implements ImportBeanDefinitionRegistrar { /** 能够获取容器中已有 BeanDefinition 信息来作一些判断; * 好比, 若是有这两个类, 也加入类 PojoWhenHasPojo4AndPojo5 * @param importingClassMetadata 能够获取到当前类(扫描到的类)的全部注解信息 * @param registry beanDefinition的注册接口 */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean hasPojo5 = registry.containsBeanDefinition(Pojo5.class.getName()); boolean hasPojo4 = registry.containsBeanDefinition(Pojo4.class.getName()); if(hasPojo4 && hasPojo5){ RootBeanDefinition beanDefinition = new RootBeanDefinition(PojoWhenHasPojo4AndPojo5.class); registry.registerBeanDefinition("pojoWhenHasPojo4AndPojo5", beanDefinition); } } }
测试:
private AnnotationConfigApplicationContext printAnnoBeans(Class clazz) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(clazz); Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println); return ctx; } @Test public void testImport(){ // PojoBean*.java并没有注解类, 可是会初始化纳入spring容器管理! -> @Import的做用! ApplicationContext ctx = printAnnoBeans(ImportTestConfig.class); }
output: 能够看到 PojoWhenHasPojo4AndPojo5 的初始化!
PojoBean[无注解java类] 初始化~~~ PojoBean2[无注解java类] 初始化~~~ PojoBean3[无注解java类] 初始化~~~ Pojo4[无注解java类] 初始化~~~ Pojo5[无注解java类] 初始化~~~ PojoWhenHasPojo4AndPojo5[无注解java类] 初始化~~~ org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory importTestConfig com.niewj.bean.PojoBean com.niewj.bean.PojoBean2 com.niewj.bean.PojoBean3 com.niewj.bean.Pojo4 com.niewj.bean.Pojo5 pojoWhenHasPojo4AndPojo5
注意: 经过 ctx.getBean("beanId") 调用, 获得的是 getObject()方法返回的对象的实际内容;
经过ctx.getBean("&beanId")调用, 获得的才是实际的FactoryBean对象
package com.niewj.bean; public class Pojo7 { public Pojo7(){ System.out.println("Pojo7[无注解java类] 初始化~~~"); } }
package com.niewj.bean; import org.springframework.beans.factory.FactoryBean; public class Pojo7FactoryBean implements FactoryBean<Pojo7> { @Override public Pojo7 getObject() throws Exception { System.out.println("Pojo7FactoryBean---FactoryBean---初始化"); return new Pojo7(); } @Override public Class<?> getObjectType() { return Pojo7.class; } @Override public boolean isSingleton() { return false; } }
private AnnotationConfigApplicationContext printAnnoBeans(Class clazz) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(clazz); Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println); return ctx; } @Test public void testImport(){ // PojoBean*.java并没有注解类, 可是会初始化纳入spring容器管理! -> @Import的做用! ApplicationContext ctx = printAnnoBeans(ImportTestConfig.class); Pojo7 bean1 = ctx.getBean("pojo7", Pojo7.class); System.out.println(bean1); Pojo7FactoryBean bean2 = ctx.getBean("&pojo7", Pojo7FactoryBean.class); System.out.println(bean2); }
output: 看最后两行: 说明了 FactoryBean的特征: &beanId获得是 FactoryBean; beanId获得是 getObject()返回的实际Bean!
PojoBean[无注解java类] 初始化~~~ PojoBean2[无注解java类] 初始化~~~ PojoBean3[无注解java类] 初始化~~~ Pojo4[无注解java类] 初始化~~~ Pojo5[无注解java类] 初始化~~~ PojoWhenHasPojo4AndPojo5[无注解java类] 初始化~~~ org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory importTestConfig com.niewj.bean.PojoBean com.niewj.bean.PojoBean2 com.niewj.bean.PojoBean3 com.niewj.bean.Pojo4 com.niewj.bean.Pojo5 pojo7 pojoWhenHasPojo4AndPojo5 Pojo7FactoryBean---FactoryBean---初始化 Pojo7[无注解java类] 初始化~~~ com.niewj.bean.Pojo7@2bbf180e com.niewj.bean.Pojo7FactoryBean@163e4e87
向spring容器中注册组件有四种方式:
@Import导入普通bean也有四种方式: