spring 注解-- 配置组件

@ComponentScan(value = “com.example.demo”)

加载指定包,默认加载@Component、@Controller、@Service、@Repository

includeFilters

限定加载范围

@ComponentScan(
value = "com.example.demo",
includeFilters = @ComponentScan.Filter(
				type = FilterType.ANNOTATION, 
				classes = {Service.class}), 	// 只加载@Service
				useDefaultFilters = false)	// useDefaultFilters 必须设置成false,否则Filter不生效,默认加载所有。

includeFilters.type

type = FilterType.ANNOTATION,classes = {Service.class}	 //按注解(@Service)过滤	
type = FilterType.ASSIGNABLE_TYPE,classes = {xxx.class}  //按指定类(xxx.class)过滤
type = FilterType.CUSTOM, classes = {MyTypeFilter.class}  //按自定义的filter过滤

自定义filter过滤

public class MyTypeFilter implements TypeFilter {

    /**
     * @param metadataReader    获取当前操作类的信息,源信息(metadata)
     * @param metadataReaderFactory 获取上下文信息
     * @return
     * @throws IOException
     */
    @Override
    public boolean match(MetadataReader metadataReader, 
			    MetadataReaderFactory metadataReaderFactory) throws IOException {
			    
        metadataReader.getAnnotationMetadata(); //获取扫描到的类注解信息

        ClassMetadata classMetadata = metadataReader.getClassMetadata();   //获取扫描到的类信息
						 
        String className = classMetadata.getClassName();
        System.out.println("--------------"+className);
        if(className.contains("Person")){
            return true;
        }
        return false;
    }
}

@Configuration + @Bean

@Configuration
@ComponentScan(value = "com.example.demo.configuration")
public class MyConfig {
    @Bean
    public Person person(){		// 默认方法名为对象名,返回的对象默认单例
        return new Person("xujj", 18);
    }
    
	@Bean(name="person1")	//自定义对象名 : person1
}

@Scope

@Scope("prototype")		// 原型模式
@Configuration
public class MyConfig {
    @Bean
    public Person person(){
      return new Person("xujj", 18);
    }
}

@Scope() 默认单例
@Scope(“singelton”) 单例模式,即每次调用返回同一个实例
@Scope(“prototype”) 原型模式,即每次调用返回一个新的实例
@Scope(“request”) 每次请求创建一个实例(主要应用于web
@Scope(“session”) 同一session只创建一个实例(主要应用于web)

验证Bean是否单例:

public class MyTest {
    @Test
    public void test() {
        ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class);
        Object bean1 = app.getBean("person");
        Object bean2 = app.getBean("person");
        System.out.println(bean1 == bean2);
    }
}

@Lazy

延迟加载,默认true,容器启动时,不创建对象,对象调用时才创建。
懒加载只针对单例Bean起作用

不添加@Lazy,启动时加载bean

@Configuration
public class MyConfig {
    @Bean
    public Person person(){
        System.out.println("将对象添加到IoC容器中");
        return new Person("Tom",18);
    }
}
public class MyTest {
    @Test
    public void test(){
        ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println("IoC容器创建完成");
        app.getBean("person");
    }
}

输出结果:
将对象添加到IoC容器中
IoC容器创建完成

添加 @Lazy

@Configuration
public class MyConfig {
    @Lazy
    @Bean
    public Person person(){
        System.out.println("将对象添加到IoC容器中");
        return new Person("Tom",18);
    }
}

输出结果:
IoC容器创建完成
将对象添加到IoC容器中

@Conditional

满足条件则注册、装载,spring4开始提供。

根据不同的系统,实例化不同的对象。
可通过修改VM参数:-ea Dos.name=Linux,来尝试Linux系统的情况。

@Configuration
public class MyConfig {
    @Conditional(WinCondition.class)	//判断条件
    @Bean
    public Person tom(){
        System.out.println("将对象Tom添加到IoC容器中");
        return new Person("Tom",18);
    }

    @Conditional(LinuxCondition.class)
    @Bean
    public Person lily(){
        System.out.println("将对象lily添加到IoC容器中");
        return new Person("lily",17);
    }
}
public class WinCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //从IoC容器中拿到已经实例化的对象
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //bean工厂
        Environment environment = context.getEnvironment(); //环境变量
        String osName = environment.getProperty("os.name");
        if(osName.contains("Windows")){
            return true;
        }
        return false;
    }
}
public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //从IoC容器中拿到已经实例化的对象
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Environment environment = context.getEnvironment();
        String osName = environment.getProperty("os.name");
        System.out.println(osName);
        if(osName.contains("Linux")){
            return true;
        }
        return false;
    }
}

条件控制

并不是所有的插件都遵循spring.factories规则。比如 RedisAutoConfiguration类,基于@ConditionalOnClass({RedisOperations.class})条件控制,装载redis的配置。

spring-autoconfigure-metadata.properties 文件

resources\META-INF目录下创建该文件,表示如果引用的上层项目中存在com.gupaoedu.DemoClass该类,则加载当前项目中类。
文件内容:
com.gupaoedu.autoconfiguration.demo.GupaoConfiguration.ConditionalOnClass=com.gupaoedu.DemoClass

@Import

直接导入:

@Configuration
@Import(value = {Cat.class})	//直接导入 Cat.class
public class MyConfig {

}

自定义规则导入:实现 ImportSelector 接口

@Configuration
@Import(value = {MyImportSelector.class})
public class MyConfig {
}

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.gupaoedu.project.entity.Company",
                            "com.gupaoedu.project.entity.Member"}; // 传入需要导入的配置类、或者bean
    }
}

手动注入:实现ImportBeanDefinitionRegistrar 接口

@Import(value = {MyImportBeanDefinitionRegistrar.class})
public class MyConfig {

}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     *
     * @param importingClassMetadata  当前类的注解信息
     * @param registry 完成BeanDefinition的注册
     */
    @Override
    public void registerBeanDefinitions(
				AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean company = registry.containsBeanDefinition("com.gupaoedu.project.entity.Company");
        boolean member = registry.containsBeanDefinition("com.gupaoedu.project.entity.Member");

        if(company && member){
            BeanDefinition beanDefinition = new RootBeanDefinition(User.class);
            registry.registerBeanDefinition("user", beanDefinition);
        }
    }
}

通过FactoryBean注入:实现 FactoryBean 接口

@Configuration
public class MyConfig {
    @Bean
    public MyFactoryBean monkey(){
        return new MyFactoryBean();
    }
}
public class MyFactoryBean implements FactoryBean<Monkey> {
    @Nullable
    @Override
    public Monkey getObject() throws Exception {
        return new Monkey();
    }

    @Nullable
    @Override
    public Class<?> getObjectType() {
        return Monkey.class;
    }

    @Override
    public boolean isSingleton() {
        return true; 	// true:单例,false:非单例
    }
}

通过 isSingleton() 控制是否单例

测试类:

public class MyTest {
    @Test
    public void test(){
        ApplicationContext app = new AnnotationConfigApplicationContext(MyConfig.class);

        //通过FactoryBean注入的值
        System.out.println("============" + app.getBean("monkey").getClass());
        Object monkey1 = app.getBean("monkey");
        Object monkey2 = app.getBean("monkey");
        System.out.println("是否单例:" + monkey1 == monkey2);

        //拿到构建monkey的FactoryBean
        Object monkeyFactoryBean = app.getBean("&monkey");
        System.out.println(monkeyFactoryBean);

        String [] beanNames = app.getBeanDefinitionNames();
        System.out.println(Arrays.toString(beanNames).replaceAll("\\[|\\]","").replaceAll(", ","\n"));
    }

}

注意:app.getBean("&monkey") 获取 MyFactoryBean 的实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值