第一种:xml配置bean,beans.xml中的一个bean
<bean id="persion" class="com.thl.bean.Persion">
<property name="uid" value="1"></property>
<property name="name" value="1900614@qq.com"></property>
<property name="pwd" value="123456"></property>
</bean>property对应pojo,这种是通过Get和Set方法注入到bean中的测试:
@Test
public void beanTestXml() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Persion persion = (Persion) context.getBean("persion");
System.out.println(persion);
}第二种:扫描的方式 ComponentScan
会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中
实际上是他们中有一个共同注解@Component
beans中配置
<context:component-scan base-package="com.thl.service">
或者通过 @ComponentScan注解
并且可以自定义扫描方式,自定义需要实现TypeFilter 接口
举例:
// excludeFilters 排除那些组件
// includeFilters 只包含哪些组件 但是要配置 useDefaultFilters = false
//
/**
* ANNOTATION:指定类
* ASSIGNABLE_TYPE:指定类型
* ASPECTJ:ASPECTJ表达式
* REGEX:正则表达式
* CUSTOM:自定义规则 需要实现TypeFilter
*/
// jdk8 @ComponentScan可以多写几次 指定扫描策略
@ComponentScan(value = "com.thl", includeFilters = {//按照注解排除 加了 Repository注解的
// @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Repository.class}),
//ASSIGNABLE_TYPE 指定类型 Persion以及子类 包含进来
// @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {Persion.class})
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyScanFilter.class})
}, useDefaultFilters = false)
public class ComponentScanCofig {
}
public class MyScanFilter implements TypeFilter {
/**
* @param metadataReader 读取到当前正在扫描类的信息
* @param metadataReaderFactory 读取到其他任何类的信息
* @return
* @throws IOException
*/
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类的注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String className = classMetadata.getClassName();//拿到类名
System.out.println("自定义扫描的类" + className);
if (className.toLowerCase().contains("dao")) {//如果包含dao关键字
return true;
}
//获取当前类的路径
Resource resource = metadataReader.getResource();
return false;
}
}
/**
* 测试 ComponetScan 扫描
*/
@Test
public void iocTest() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComponentScanCofig.class);
//获取扫描所有的bean
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}第三种:@Bean 配置类获取bean
并且可以懒加载@Lazy和多种作用域@Scop
/** @Scope()
* singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例 spring启动的时候启动
* prototype表示每次获得bean都会生成一个新的对象 启动的时候不会启动 调用的时候创建
* request表示在一次http请求内有效(只适用于web应用)
* session表示在一个用户会话内有效(只适用于web应用)
*/
**
* 懒加载 spring启动不加载 第一次获取的时候加载
*/
@Configuration
public class Beans {
@Lazy
@Scope(value = "prototype")
@Bean("P1")
public Persion persionRoot() {
return new Persion(1, "root", "123456");
}
}
第四种:@Import注入bean
@Import接收一个数组,放入其中即可加入到IOC容器中
@Import({A.class,B.class})
public class Beans{}并且可以通过实现ImportSelector收集需要导入多个配置类 实现ImportBeanDefinitionRegistrar 动态注入bean
举例:
@Configuration
@Import({MyImportSelect.class,MyImportBeanDefinitionRegistrar.class})//快速导入组件,名字为全类名 容器就会注册这个组件
public class Beans {
}
public class MyImportSelect implements ImportSelector {
//标注 @import的所有类名
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//返回值为导入到容器的所有全类名 可以返回空数组 但是不要返回null
// System.out.println(Bule.class.getName());
return new String[]{Bule.class.getName(), Green.class.getName()};
}
}
class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
//AnnotationMetadata 当前类的注解信息
//BeanDefinitionRegistry BeanDefinition注册类
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean red = registry.containsBeanDefinition("red");//是否有红色
if(!red){
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Red.class);
registry.registerBeanDefinition("red",rootBeanDefinition );
}
}
}
第五种:@Conditional满足条件创建Bean
@Configuration
//@Conditional({LinuxCondition.class})//放在类上 满足当前条件 这个类中配置的所有bean才会生效 统一设置
public class Beans {
@Bean("WinP1")
@Conditional({WinCondition.class})
public Persion WinP1() {
return new Persion(1, "user", "123456");
}
@Bean("LinuxP1")
@Conditional({LinuxCondition.class})
public Persion LinuxP1() {
return new Persion(1, "root", "123456");
}
@Bean
public MyFactoryBean myFactoryBean(){
return new MyFactoryBean();
}
}
/**
*
* @param context 判断上下文使用的环境
* @param metadata 标注了当前Condition的注释信息
* @return
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//IOC的beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//类加载器
ClassLoader classLoader = context.getClassLoader();
//当前环境信息
Environment environment = context.getEnvironment();
//bean的注册定义
BeanDefinitionRegistry registry = context.getRegistry();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}
//LinuxCondition也是一样第六种:通过BeanFactory创建
需要实现FactoryBean接口
public class MyFactoryBean implements FactoryBean<Red> {
public Red getObject() throws Exception {
//调用 getObject创建的对象
System.out.println("getObject的到 red bean");
return new Red();
}
public Class<?> getObjectType() {
return Red.class;
}
public boolean isSingleton() {
return true;
}
}
@Configuration
public class Beans {
@Bean
public MyFactoryBean myFactoryBean(){
return new MyFactoryBean();
}
}
@Test
public void beans() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Beans.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
// name 前面加上& 获取bean本身 直接写name获取工厂返回的bean
Object myFactoryBean = context.getBean("myFactoryBean");
System.out.println(myFactoryBean);
}
版权声明:本文为qq_40859018原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。