Spring注解开发总结

1,@Configuration 

//配置类==配置文件

@Configuration  //告诉Spring这是一个配置类

一句话概括就是 @Configuration 中所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。

@Configuration 注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    String value() default "" ;
}

从定义来看, @Configuration 注解本质上还是 @Component,因此 <context:component-scan/> 或者 @ComponentScan 都能处理@Configuration 注解的类。

@Configuration 标记的类必须符合下面的要求:

  • 配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理)。
  • 配置类不能是 final 类(没法动态代理)。
  • 配置注解通常为了通过 @Bean 注解生成 Spring 容器管理的类,
  • 配置类必须是非本地的(即不能在方法中声明,不能是 private)。
  • 任何嵌套配置类都必须声明为static
  • @Bean 方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration,也不会被特殊处理,只会作为普通的 bean)。

 

加载过程

Spring 容器在启动时,会加载默认的一些 PostPRocessor,其中就有 ConfigurationClassPostProcessor,这个后置处理程序专门处理带有 @Configuration 注解的类,这个程序会在 bean 定义加载完成后,在 bean 初始化前进行处理。主要处理的过程就是使用 cglib 动态代理增强类,而且是对其中带有 @Bean 注解的方法进行处理。

2,@Bean

Spring@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。默认bean的名称就是其方法名。但是也可以指定名称;

使用@Bean注解的好处就是能够动态获取一个Bean对象,能够根据环境不同得到不同的Bean对象。或者说将Spring和其他组件分离(其他组件不依赖Spring,但是又想Spring管理生成的bean)。

//给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id

   @Bean("person")

   public Person person01(){

      return new Person("lisi", 20);

   }

类似beans.xml

 

 

3,@ComponentScans

@ComponentScan是告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。

基本的basePackages参数是用于扫描带注释组件的基本包。那么excludeFilters呢?其他参数呢?

basePackageClasses:对basepackages()指定扫描注释组件包类型安全的替代。

excludeFilters:指定不适合组件扫描的类型。

includeFilters:指定哪些类型有资格用于组件扫描。

lazyInit:指定是否应注册扫描的beanslazy初始化。

nameGenerator:用于在Spring容器中的检测到的组件命名。

resourcePattern:控制可用于组件检测的类文件。

scopedProxy:指出代理是否应该对检测元件产生,在使用过程中会在代理风格时尚的范围是必要的。

scopeResolver:用于解决检测到的组件的范围。

useDefaultFilters:指示是否自动检测类的注释 

@ComponentScans(

      value = {

           @ComponentScan(value="com.dths",includeFilters = {

/*               @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),

                 @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/

                 @Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})

           },useDefaultFilters = false)  

      }

      )

//@ComponentScan  value:指定要扫描的包

//excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件

//includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件

//FilterType.ANNOTATION:按照注解

//FilterType.ASSIGNABLE_TYPE:按照给定的类型;

//FilterType.ASPECTJ:使用ASPECTJ表达式

//FilterType.REGEX:使用正则指定

//FilterType.CUSTOM:使用自定义规则

自定义TypeFilter指定过滤规则

 

4,@Scope, @Lazy

Scope,也称作用域,在 Spring IoC 容器是指其创建的 Bean 对象相对于其他 Bean 对象的请求可见范围。在 Spring IoC 容器中具有以下几种作用域:基本作用域(singletonprototype),Web 作用域(reqeustsessionglobalsession),自定义作用域。 
1
Spring 的作用域在装配 Bean 时就必须在配置文件中指明,配置方式如下(以 xml 配置文件为例):

<!-- 具体的作用域需要在 scope 属性中定义 -->
<bean id="XXX" class="com.XXX.XXXXX" scope="XXXX" />

singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例。

prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。

request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效。

session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效。

globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效。

  其中比较常用的是singletonprototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该idBeanSpring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。

  如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。 
   
 2、基于注解开发时,@scope完成bean的作用域配置默认是单例模式(singleton)如果需要设置的话可以修改对应值与以上提到的一致例如:@scope(“prototype”)

// 默认是单实例的

   /**

    * ConfigurableBeanFactory#SCOPE_PROTOTYPE

    *

    * @see ConfigurableBeanFactory#SCOPE_SINGLETON

    * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST

    *      request

    * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION

    *      sesssion @return\

    * @Scope:调整作用域 prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。 每次获取的时候才会调用方法创建对象;

    *              singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。

    *              以后每次获取就是直接从容器(map.get())中拿, request:同一次请求创建一个实例

    *              session:同一个session创建一个实例

    *

    *              懒加载: 单实例bean:默认在容器启动的时候创建对象;

    *              懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;

    *

    */

// @Scope("prototype")

   @Lazy

   @Bean("person")

   public Person person() {

      System.out.println("给容器中添加Person....");

      return new Person("张三", 25);

   }

@Lazy用于指定该Bean是否取消预初始化。主要用于修饰Spring Bean类,用于指定该Bean的预初始化行为,使用该Annotation时可以指定一个boolean型的value属性,该属性决定是否要预初始化该Bean

  • lazy代表延时加载,lazy=false,代表不延时,如果对象A中还有对象B的引用,会在A的xml映射文件中配置b的对象引用,多对一或一对多,不延时代表查询出对象A的时候,会把B对象也查询出来放到A对象的引用中,A对象中的B对象是有值的。
  • lazy=true代表延时,查询A对象时,不会把B对象也查询出来,只会在用到A对象中B对象时才会去查询,默认好像是false,你可以看看后台的sql语句的变化就明白了,一般需要优化效率的时候会用到。

5,@Conditional

条件注解,可以根据不同的条件来做出不同的事情。在Spring中条件注解可以说是设计模式中状态模式的一种体现方式,同时也是面向对象编程中多态的应用部分。

Spring框架中,当我们使用条件注解时,我们会为每种独立的条件创建一个类,根据这个类对应的条件的成立情况我们来选择不同的任务来执行。当然我们在声明任务时,一般使用接口来声明。因为我们会在Spring的配置类中指定具体条件下的具体类。接下来,我们将来看一下Spring框架中@Conditional注解的具体使用方式。

//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;

@Conditional({ WindowsCondition.class })

6,@Import

通过导入的方式实现把实例加入springIOC容器中,通过查看@Import源码可以发现@Import注解只能注解在类上,以及唯一的参数value上可以配置3种类型的值ConfigurationImportSelectorImportBeanDefinitionRegistrar,源码如下:

 

接下来就分别来看看三种方式具体使用:

a,基于Configuration也就是直接填对应的class数组

bean目录下新增两个类SquareCircular如下:

 

MainConfig注解配置中增加@Import注解如下:

 

b,基于自定义ImportSelector的使用

定义一个MyImportSelector如下:

 

MainConfig注解配置修改如下

 

 

三角形 实例同样加入到spring容器中了

c,基于ImportBeanDefinitionRegistrar的使用

新建一个ImportBeanDefinitionRegistrar如下:

 

修改MainConfig注解配置如下:

 

//@Import导入组件,id默认是组件的全类名

/**

    * 给容器中注册组件;

    * 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component[自己写的类]

    * 2)、@Bean[导入的第三方包里面的组件]

    * 3)、@Import[快速给容器中导入一个组件]

    *    1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名

    *    2)、ImportSelector:返回需要导入的组件的全类名数组;

    *    3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中

    *    4)、使用Spring提供的

    * FactoryBean(工厂Bean;

    *    1)、默认获取到的是工厂bean调用getObject创建的对象

    *    2)、要获取工厂Bean本身,我们需要给id前面加一个& &colorFactoryBean

    */

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值