Spring常用注解-学习Spring注解驱动开发--Day 1

Spring 注解驱动开发

Day 1

该课程主要讲述使用Spring注解来进行开发

注解整理

  • @Configuration

    该注解标注一个类为Spring配置类,表示该类代替原始的xml配置文件

  • @ComponentScan

    该注解用于配置Spring将哪些类装进IOC容器中,在注解中,参数value填写所扫描的包名,includeFilters和excludeFilters用于配置装载Bean的包含规则和过滤规则。其中有@ComponentScan.Filter注解用于配置通过某种方式进行类文件的过滤

  • @ComponentScan.Filter

    该注解用在@ComponentScan的注解中的includeFilters和excludeFilters中,用于设定扫描规则共有五种规则

    1. FilterType.ANNOTATION //该注解通过注解类型进行过滤
    2. FilterType.ASSIGNABLE_TYPE//该注解通过类的类型进行过滤
    3. FilterType.ASPECTJ//该注解通过Aspectj的表达式,基本上不会用到
    4. FilterType.REGEX//该注解按照正则表达式进行匹配
    5. FilterType.CUSTOM//自定义规则

下面代码为FilterType.CUSTOM的使用说明

@Configuration
@ComponentScan(value = "com.lym",includeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
},useDefaultFilters = false)
public class Config {
    @Bean("person")
    public Person person01(){
        return new Person(20,"lisi");
    }
}//上述类为配置类

public class MyTypeFilter implements TypeFilter {
//该类为自定义的配置类,该类需要实现TypeFilter接口
    /*
    * metadataReader:读取到的正在扫描的类的信息
    * metadataReaderFactory 可以获取带其他任何类的信息
    * */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当前类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前正在扫描的类的类信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //获取当前类资源
        Resource resource = metadataReader.getResource();
        String className = classMetadata.getClassName();
        System.out.println("--->" + className);
        if(className.contains("er")) return true;//当类名中包含er返回true
        return false;
    }
}
  • @ComponentScans 该注解参数为ComponentScan[] 可用于设置多个ComponentScan

  • @Service @Controller @Respositiory @Component 以上四个个注解均为自动装配标注,如果该类在配置类的ComponentScan中的包中,那么该类的默认id为类名的第一个字母小写。但是以上四个注解只能添加在自己写的类上,对于其他的类则无可奈何

  • @Bean 用来代替xml文件中的标签,可以将组件导入IOC容器

@Bean("person")//设置id,模式是使用方法名为id,如果两处有冲突则以这里为准
public Person person01(){//默认使用方法名做id
    return new Person(20,"lisi");//使用构造方法注入属性,也可以直接调用set方法注入属性
}
  • @Import 快速给容器中导入一个组件
  1. @Import(要导入容器的组件):容器中就会自动注册这个组件,id默认是全类名。
  2. ImportSelector:返回需要导入的组件的全类名数组,下面介绍ImportSelector的使用方法。
@Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
//在Import注解中,添加MyImportSelector.class
@Configuration
@ComponentScan(value = "com.lym")
public class Config {}
public class MyImportSelector implements ImportSelector {//实现ImportSelector接口
    //返回值就是导入到容器中的组件全类名
    //AnnotationMetadata:当前标志@Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //不能返回null,返回null会报空指针异常。
        return new String[]{"com.lym.bean.Red"};
    }
}
  1. ImportBeanDefinitionRegistrar:手动注册bean到容器中。与ImportSelector使用方法大体相似
@Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
//在Import注解中,添加MyImportBeanDefinitionRegistrar.class
@Configuration
@ComponentScan(value = "com.lym")
public class Config {}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /*
    * AnnotationMetadata:当前类的注解信息
    * BeanDefinitionRegistry: BeanDefinition注册类:
    * 把所有需要添加在容器中的bean:调用
    * BeanDefinitionRegistry.registerBeanDefinition手工注册
    * */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean definition = registry.containsBeanDefinition("com.lym.bean.Color");
        boolean definition1 = registry.containsBeanDefinition("com.lym.bean.Red");
        if(definition && definition1){
            //RootBeanDefinition可以指定Bean的定义信息,比如bean的作用域,bean的类型等等
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
            registry.registerBeanDefinition("rainBow",rootBeanDefinition);
        }
    }
}
  1. Spring提供的FactoryBean(工厂Bean):首先创建一个工厂类,通过在Spring配置类中进行@Bean的配置,该类可以生成两种Bean,一种为工厂类中的产品类型,即实现的getObject类型的对象,另一种为工厂类本身类型,在getBean的参数加一个&前缀。
//该类需要实现FactoryBean接口,这样该类就成为了一个BeanFactory类
public class ColorFactoryBean implements FactoryBean<Color> {
    //返回一个Color对象,这个对象会添加到容器中
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }
    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }
    //return true 这个bean是单实例,在容器中保存一份
    //return false 多实例,每次获取都会创建实例
    @Override
    public boolean isSingleton() {
        return true;
    }
}
//在配置类中通过@Bean方式将此对象载入IOC容器
@Bean
public ColorFactoryBean colorFactoryBean(){
    return new ColorFactoryBean();
}

Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");
//获得getObject返回的类型
Object colorFactoryBean = applicationContext.getBean("&colorFactoryBean");
//获得工厂类型
  • @Value 在一个类标注@Component后若成员变量有默认值,则可以通过此注解在成员变量的上方标注
  • @Lazy 对于单实例bean,默认在容器启动的时候创建对象,设置了懒加载模式后,第一次使用Bean的时候创建对象。
  • @Scope("")

该注解设置Bean的作用域范围,常用的有两种情况,默认为singleton:单实例(默认值)单实例情况下,IOC容器启动会调用方法创建对象放到ioc容器中,以后每次获取就是从容器中拿。
prototype:多实例 在多实例情况下IOC容器启动并不会区调用方法创建对象放在容器中,每次创建都会调用该实例所属类的构造方法。
此外还有一些SpringMVC相关联的设置。例如request,session等。

  • @Conditional() 该注解可作用于方法或类上,作用为按照一定的条件进行判断,满足条件给容器注册bean,下面为具体应用案例
@Bean("bill")
@Conditional({WindowsCondition.class})
public Person person01(){
    return new Person(62,"Bill Gates");
}
@Bean("linus")
@Conditional({LinuxCondition.class})
public Person person02(){
    return new Person(48,"linus");
}//上面两个方法为Spring Config类中的两个Bean方法均设定了Condition
//要使用Condition,需要实现Springframework中的Condition接口
public class LinuxCondition implements Condition {
    /*
    * 参数说明:
    * ConditionContext:判断条件能使用的上下文环境
    * AnnotatedTypeMetadata :注释信息
    */

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //是否是Linux系统
        //1. 能获取到ioc使用的bean factory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //2. 获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        //3. 获取当前环境
        Environment environment = context.getEnvironment();
        //4. 获取到bean定义的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        //可以判断容器中的bean注册情况,也可以给容器中注册bean

        String property = environment.getProperty("os.name");
        if(property.contains("linux")){
            return true;
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值