SpringDay2

SpringDay2

使用注解开发Spring



一、注解驱动的意义

1.1)什么是注解驱动

注解启动时使用注解的形式替代xml配置,将繁杂的spring配置文件从工程中彻底消除掉,简化书写

在这里插入图片描述

1.2)注解驱动的弊端

  • 为了达成注解驱动的目的,可能会将郧县很简单的书写变得更加复杂
  • XML中配置第三方开发的资源是很方便的,但是使用注解驱动无法在第三方卡法的资源中进行编辑,因此会增大开发工作量。

这个很容易理解,第三方的配置使用xml只需要ref将第三方资源引入即可,但是如果使用注解,则需要写一个类将所需要的资源引入到我们的项目中。在这里插入图片描述

2)常用注解

2.1)启动注解功能

  • 启动注解扫描,加载类中配置的注解项

    <context:component-scan base-package="packageName"/>
    
  • 说明:

    • 在进行包所扫描时,会对配置的包以及子包中所有文件进行扫描
    • 扫描过程是以文件夹递归迭代的形式进行的
    • 扫描过程仅读取合法的java文件
    • 扫描时仅读取spring可识别的注解
    • 扫描结束后会将可识别的有效注解转化未spring对应的资源加入Ioc容器
  • 注意:

    • 无论时注解格式还是XML配置格式,最终都是将资源加载到IoC容器,差别仅仅是数据读取方式不同
    • 从加载效率上来说注解更优于XMl配置文件

2.2)bean的定义

名称:@Component @Controller @Service @Repository
类型:类注解
位置:类定义上方
作用:设置该类为spring管理的bean
范例:

@Component
public class ClassName{}

说明:@Controller@service@Repository@Component的衍生注解,功能同@Component相同,提高了代码可读性
相关属性:Value(默认):定义bean的访问id

2.3)bean的作用域

名称:@Scope
类型:类注解
作用:设置该类作为bean对应的Scope属性
范例:

@Scope
public class ClassName{}

相关属性:value:定义bean作用域,默认为singleton

2.4)bean的生命周期

名称:@PostConstruct、@PreDestory
类型:方法注解
作用:设置该类作为bean对应的生命周期方法
范例:

@PostContruct
public void init(){System.out.printLn("init...");}

相关属性:value:定义bean的作用域,默认为singleton

2.5)加载第三方资源

名称:@bean
类型:方法注解
作用:设置该方法的返回值为spring管理的bean
范例:

@bean("dataSource")
public DruidDataSource createDataSource(){return ...;}

说明:

  • 因为第三方bean无法在其源码上进行修改,使用@bean解决第三方bean的引入问题
  • 该注解用于代替XML配置中的静态工厂与实例工厂创建bean,不区分方法是否为静态或非静态
  • @Bean所在的类必须被spring扫描加载,否则该注解无法生效
    相关属性:value:定义bean的访问id

2.6)bean的非引用类型注入

名称:@value
类型:属性注解、方法注解
作用:设置对应属性的值或对方法进行传参
范例“:

@value("${jdbc.username}")
private String username;

说明:

  • value值仅支持非引用类型数据,赋值时对方法的所有参数全部赋值
  • value值支持读取properties文件中的属性值,通过类属性将properties中数据传入类中。
  • value值支持SpEL(第一天有解释)
  • @value注解如果添加在属性上方,可以省略set方法(因为set的方法就是为了给属性赋值,注解的作用就是可以自动赋值,所以可以省略)
    相关属性:value:定义对应的属性值或参数值

2.7)bean的引用类型属性注入

名称:@Autowired、@qualifier
类型:属性注解、方法注解
作用:设置对应属性的对象或对方法进行引用各类型传参
范例:

@Autowire(requiered=false)//默认按类型自动装配,
@Qualifier("userDao")//指定自动装配的bean的ID
private userDao userDao;

当出现相同类型的bean,使用@primary定义在类的上方可以提高按类型自动装配的优先级,多个@primary会导致优先级设置无效
@inject@Named是JSR330规范中的注解,功能与@Autowire@Qualifier完全相同,适用于不同架构场景
@ReSource是JSR250规范中的注解,可以简化书写格式
@ReSource相关属性:

  • name:设置注入的bean的id
  • type:设置注入的bean的类型,接受的参数为Class类型

相关属性:required:定义该属性是否允许null

2.8)加载properties文件

名称:@propertySource
类型:类注解
作用:加载properties文件中的属性值。目前我最多用于加载jdbc的properties文件
范例:

@PropertySource(value = "classpath:filename.properties")
public class ClassName {
    @Value("${propertiesAttributeName}")
    private String attributeName;
}

说明:不支持*通配格式,一旦加载,所有的spring控制的bean中均可使用对应的属性值
相关属性:value:加载properties文件名。ignoreResourceNotFound:如果资源未找到,是否忽略,默认为false

2.9)纯注解格式

名称:@Configuration、@ComponentScan
类型:类注解
作用:设置当前类为spring核心配置加载类
范例:

@Configuration
@ComponentScan("scanPackageName")
public class SpringConfigClassName{
}

说明:

  • 核心配合类用于替换spring核心配置文件,此类可以设置空的,不设置变量与属性
  • bean扫描工作使用注解@componentScan 代替 AnnotationConfigApplicationContext
  • 加载纯注解格式上下文对象需要使用 AnnotationConfigApplicationContext

AnnotationConfigApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.class);

2.10) 第三方bean配置与管理

名称;@Import
类型:类注解
作用:导入第三方bean作为spring控制的资源
范例:

@Configuration
@Import(OtherClassName.class)
//该注解仅仅允许注解一次,如果需要导入多个,需要使用数组的形式进行设定
//在被导入的类中可以继续使用@import导入其他资源
//@Bean所在的可以使用导入的形式进行spring容器,无需申明为bean
public class ClassName {
}

3)bean加载控制

3.1)依赖加载

(1)@DependsOn
类型:类注解、方法注解
作用:控制bean的加载顺序,使其指定的bean加载完毕后,在加载
范围:

@DependsOn("beanId")
public class ClassName {
}

说明:

  • 在配置方法上,使用@DependsOn指定的bean优先于@Bean配置的bean进行加载
  • 配置类上,使用@DependsOn指定的bean优先于当前类中所有@bean配置的bean进行加载
  • 配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载
  • value:设置当前bean所依赖的bean的id
    (2)@Order
  • 名称:@Order
  • 类型:配置类注解
  • 作用:控制配置类的加载顺序
  • 范围:
@Order(1)
   public class SpringConfigClassName {
}

(3)@Lazy

  • 名称:@Lazy
  • 类型:类注解、方法注解
  • 作用:控制bean的加载时机,使其延迟加载
  • 范围:
 @Lazy
	public class ClassName {}

3.2)依赖加载应用场景

@DependsOn:微信订阅号,发布订阅消息的bean的加载顺序控制
@Lazy:软件危机后出现对应的应急预案处理是启动容器加载时机
@Order:多个种类的配置出现后,优先加载系统级的,然后加载业务级的,避免细粒度的加载控制

4)IoC底层核心原理

4.1)组件扫描器

  • 开发过程中,需要根据需求加载必要的bean,或排除指定bean

4.2)设定组件扫描加载过滤器

  • 名称:@ComponentScan
  • 类型:类注解
  • 作用:设置spring配置加载类扫描规则
  • 范例:
@ComponentScan(
   value="com.itheima",	           //设置基础扫描路径
   excludeFilters =                          //设置过滤规则,当前为排除过滤
   @ComponentScan.Filter(            //设置过滤器
       type= FilterType.ANNOTATION,  //设置过滤方式为按照注解进行过滤
       classes=Repository.class)     //设置具体的过滤项,过滤所有@Repository修饰的bean
   )
includeFilters:设置包含性过滤
excludeFilters:设置排除性过滤
type:设置过滤器类型

4.3)自定义组件过滤器

  • 名称:TypeFilter
  • 类型:接口
  • 作用:自定义类型过滤器
  • 范例
public class MyTypeFilter implements TypeFilter {
   public boolean match(MetadataReader mr, MetadataReaderFactory mrf) throws IOException {
       ClassMetadata cm = metadataReader.getClassMetadata();
       tring className = cm.getClassName();
       if(className.equals("com.***.dao.impl.BookDaoImpl")){
           return false;
       }
       return false;
   }
}

4.4)自定义导入器

  • bean只有通过配置才可以进入spring容器,被spring加载并控制

  • 配置bean的方法如下:

    • XML文件中使用 <bean/>标签配置
    • 使用@Component及衍生注解配置
  • 企业开发中,通常需要配置大量的bean,需要一种快速高效配置大量bean的方式
    ImprotSelector

    • 名称:importSelector
    • 类型:接口
    • 作用:自定义bean导入器
    • 范例:
    public class MyImportSelector implements ImportSelector {
     public String[] selectImports(AnnotationMetadata icm) {
         return new String[]{"com.***.dao.impl.AccountDaoImpl"};
     }
    }
    
    @Configuration
    	@ComponentScan("com.***")
    	@Import(MyImportSelector.class)
    	public class SpringConfig {
    	}
    

4.5)自定义注册器

  • 名称:ImportBeanDefinitionRegistrar
  • 类型:接口
  • 作用:自定义bean注册器
  • 范例:
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata icm, BeanDefinitionRegistry r) {
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(r, false);
        TypeFilter tf = new TypeFilter() {
            public boolean match(MetadataReader mr, MetadataReaderFactory mrf) throws IOException {
                return true;
            }
        };
        scanner.addIncludeFilter(tf);
        //scanner.addExcludeFilter(tf);
        scanner.scan("com.***");
    }
}

4.6) bean初始化过程解析

  • BeanFactoryPostProcessor

    • 作用:定义了在bean工厂对象创建后,bean对象创建前执行的动作,用于对工厂进行创建后业务处理。
    • 运行时机:当前操作用于对工厂进行处理,仅运行一次。
  • BeanPostProcessor

    • 作用:定义了所有bean初始化前后进行的统一动作,用于对bean进行创建前业务处理与创建后业务处理
    • 运行时机:当前操作伴随着每个bean的创建过程,每次创建bean均运行该操作
  • InitLalizingBean

    • 作用:定义了每个bean的初始化前进行的动作,属于非统一性动作,用于对bean进行创建前业务处理
    • 运行时机:当前操作伴随着任意一个bean的创建过程,保障其个性化业务处理
      注意:上述操作均需要被spring容器加载方可运行

4.7)繁琐的bean初始化过程处理

  • FatoryBean
    • 对单一的bean的初始化过程进行封装,达到简化配置的目的
      FactoryBean与BeanFactory区别
  • FactoryBean:封装bean的创建过程
  • BeanFactory:Spring容器顶层接口,定义了bean的相关获取操作

总结

提示:这里对文章进行总结:
主要内容:

  1. 如何开启注解驱动
  2. 生命bean可以使用那些注解
  3. 使用哪个注解可以配置第三方资源
  4. 注入非引用类型注解以及引用类型注解
  5. 记载外部属性文件的注解
  6. 如何开启纯注解以及在纯注解的过程中导入第三方资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值