Spring注解驱动

一、Spring容器

1.1、使用spring注解的优势

     ①:采用纯java代码,不再需要配置繁杂的xml文件

     ②:在配置中也可享受面向对象带来的好处

     ③:类型安全对重构可以提供良好的支持

     ④:减少复杂配置文件的同时亦能享受到springIoC容器提供的功能

1.2、@Configuration注解

定义一个MainConfig,用@Configuration注解,那MainConfig相当于xml里的beans,里面用@Bean注解的和xml里定义的bean等价,用<context:component-scanbase-package=”XXX”/>扫描该类,最终我们可以在程序里用@AutoWired或@Resource注解取得用@Bean注解的bean,和用xml先配置bean然后在程序里自动注入一样。目的是减少xml里配置。

//配置类==配置文件
@Configuration//告诉Spring这是一个配置类
public class MainConfig {
//    给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id
        @Bean
        public Person person(){
            return new Person ( "lisi","20" );
        }
}
@ComponentScan(value = "com.yjq",excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes ={Controller.class, Service.class}
)})
//@ComponentScan value:指定要扫描的包
//        excludeFilters =Filter[]:指定扫描的时候按照什么规则排除的包
//        includeFilters = Filter[]:指定扫描的时候只需要包含哪些组件
@Scope("prototype")
//    prototype:多实例的,IOC容器启动并不会去调用方法创建对象放在容器中。
//    每次获取的时候才会调用方法创建对象
//    Singleton:单实例的默认值,IOC容器启动会调用方法创建对象放到IOC容器中,以后每次获取就是直接从容器中拿

@Lazy//懒加载
//    懒加载:
//        单实例bean,默认在容器启动的时候创建对象;
//        赖加载:容器启动不创建对象,第一次使用Bean创建对象,并初始化

1.3、组件注册

Spring组件有十几种,但是核心的只有三个,分别是:Context、Core、Bean。

这三个组件的关系是什么呢?

--Context:容器;--Core:关系;--Bean:实物

IOC容器:Ioc—Inversion of Control,即“控制反转”,就是具有依赖注入功能的容器,是可以创建对象的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

即在springIOC运行容器中(Context)中,通过Core建立维护各个bean之间的关系。我们所说的组件注册就是:把bean对象交给IOC容器管理。

1.4、组件注册的几种方式

1.4.1、@Bean给容器注册组件[导入的第三方包里面的组件]

@Configuration
public class MyConfig {
    @Scope("prototype")
    @Lazy
    @Bean(value = "pp",name = "pp")
    public Person person(){
        return new Person("jiajia",26);
    }

代码中用到的注解说明:

@Configuration:配置类 相当于配置文件,告诉spring这是一个配置类

@Scope:调整作用域 ,可取值【singleton,prototype,request,session】

  -singleton:单实例(默认值):ioc容器启动会调用方法创建对象放到ioc容器中, 以后每次获取就是直接从容器中拿;

  -prototype:多实例,ioc容器启动并不会去调用方法创建对象放在容器中,每次获取的时候才会调用方法创建对象;

  -request:同一次请求创建一个实例

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

@Lazy :是只针对单实例。

  单实例Bean:默认在容器启动的时候创建对象;

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

@Bean:如果不设置value的话默认是采用方法名 person为组件名

1.4.2、@ComponentScan 组件扫描注解:包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)

@ComponentScan(value = "com.athome", excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class,Controller.class}),
    @ComponentScan.Filter(type = FilterType.REGEX,pattern = "com\\.athome\\.core\\.message\\..*")
})
@Configuration
public class MyConfig {
    @Bean
    public Person person(){
        return new Person("niHao",26);
    }
}

该注解几个重要的属性:

1)basePackages/value 表示扫描的路径是一个String[]

2)includeFilters 包含过滤器Filter[] ,指定扫描符合条件的组件

3)excludeFilters 排除过滤器Filter[] ,不扫描不符合条件的组件

4)useDefaultFilters 默认的扫描策略默认为true,如果想要用自定义的策略 该值要设为false和includeFilters一起使用  

1.4.3、@Conditional({condition}) 按条件注册bean

在spring4中引入,用到带有@Bean注解的方法上,如果给定的条件计算结果为true,则会创建这个bean,否则这个bean就会被忽略。

1.4.4、@import注解导入组件

@Import主要是用来引用第三方组件,当然也可以导入自定义的组件。

1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
        2)、ImportSelector:返回需要导入的组件的全类名数组;
        3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中

1.4.5、使用Spring提供的 FactoryBean(工厂Bean)

1)、默认获取到的是工厂bean调用getObject创建的对象
        2)、要获取工厂Bean本身,我们需要给id前面加一个&

二、Bean的生命周期

2.1、什么是bean

Spring Bean是被实例化的,组装的及被Spring容器管理的java对象。

Spring容器会自动完成@Bean对象的实例化。

创建应用对象之间的协作关系的行为称为:装配(wiring),这就是依赖注入的本质。

2.2、Bean生命周期的几种方式

* bean的生命周期:
 *          bean的创建---初始化---销毁的过程
 * 容器管理bean的生命周期
 * 我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
 *
 * 构造(对象创建)
 *         单实例:在容器启动的时候创建对象
 *         多实例:在每次获取的时候创建对象
 * 初始化:
 *         对象创建完成,并赋值后,调用初始化方法。。。
 * 销毁:
 *         单实例:容器关闭的时候;
 *         多实例:容器不会管理这个bean,容器不会调用销毁方法

.2.2.1、通过@Bean注解指定初始化和销毁方法

@Bean(initMethod = "init",destroyMethod = "destroy")

@Configuration
public class MyLifeCycleConfig {
    @Scope("prototype")
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Dog dog(){
        return  new Dog();
    }
}

applicationContext.close();关闭容器 
单实例: 调用close()关闭容器,则会调用销毁方法
多实例: 调用close()关闭容器,则不会调用销毁方法

2.2.2、实现初始化接口InitializingBean 和 销毁接口DisposableBean

通过让Bean实现InitializingBean(定义初始化逻辑);  DisposableBean(定义销毁逻辑);

@Component
public class Cat implements InitializingBean, DisposableBean {
    public Cat(){
        System.out.println("cat...构造器...");
    }
    public void destroy() throws Exception {
        System.out.println("cat ....destroy....");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("cat ...afterPropertiesSet....");
    }
}

2.2.3、 使用JSR250 java中的注解

@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法

 @PreDestroy:在容器销毁bean之前通知我们进行清理工作

@Component
public class Tiger {
    public Tiger(){
        System.out.println("tiger...constructor....");
    }
    @PostConstruct
    public void init(){
        System.out.println("tiger....@postConstruct...");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("tiger....@PreDestroy.....");
    }
}

2.2.4、使用接口  BeanPostProcessor :bean的后置处理器;

接口BeanPostProcessor是 在bean初始化前后进行一些处理工作;
         --postProcessBeforeInitialization:在初始化之前工作
         -- postProcessAfterInitialization:在初始化之后工作

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
        return bean;
    }
    
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
        return bean;
    }
}

三、自动配置

Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系复制。

3.1、@Autowired & @Qualifier & @Primary

1):默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋

​ 值。

2):如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找

​ applicationContext.getBean(“bookDao”)

3):@Qualifier(“bookDao”):使用@Qualifier指定需要装配的组件的id,而不是使用属性名

4):自动装配默认一定要将属性赋值好,没有就会报错;

5):@Primary:让Spring进行自动装配的时候,默认使用首选的bean;也可以继续使用@Qualifier指定需要装配的bean的名字,如果这两个同时使用,@Qualifier的优 先级高于@Primary

3.2、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]​​​​​​​

1):可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;

2):需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;

3.4、Aware注入Spring底层组件&原理

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx)

原理:Bean在创建对象的时候后置处理器会查看是否实现了XXXAware接口,如果实现了,会调用对应的方法将 组件注入到方法中

3.5、@Profile 根据环境注册bean

spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能。

@Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件

1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
        2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
        3)、没有标注环境标识的bean在,任何环境下都是加载的;
 

​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值