spring 常用注解 原理 逻辑 代码演示

spring 常用注解 原理 逻辑 代码演示

一、组件注册

1.1-spring注解驱动开发

image-20200511205219602

1.2-组件注册 @Configuration

// spring依赖  maven repository中按照版本查询
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.12.RELEASE</version>
</dependency>
//junit依赖
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

注意

如果创建beans.xml没有如下信息,可通过项目->右键->add framework Support->勾选spring后,resource包下右键new->XML Configuration File-> Spring Config即可

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

在这里插入图片描述

1.3-组件注册 ConfigurationBeanComponentScan(s)TypeFilter

1.3.1 Configuration Bean
//创建person类
package com.liuting.pojo;


public class Person {
    private String name;
    private String age;

    public Person() {
    }

    public Person(String name, String age) {
        System.out.println("person constructor........");
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public void init(){
        System.out.println("person.....init.....");
    }

    public void destroy(){
        System.out.println("person.....destroy.....");
    }
}

//配置类
package com.liuting.config;

import com.liuting.pojo.Person;
import org.springframework.context.annotation.*;

//配置类==配置文件
@Configuration //告诉spring这是一个配置类
public class MainConfig {
    //给容器中注册一个Bean:类型为返回值类型;id默认是方法名作为id
    @Bean 
    public Person person(){
        return new Person("lt","12");
    }
    //通过@Bean注解的value属性可指定beand的名称
    @Bean(value="person02")
    public Person person(){
        return new Person("lt","12");
    }
}

//测试类  通过AnnotationConfigApplicationContext注解式的config,它传入的就是这个配置类。相当于是传配置类的位置。
package com.liuting;



import com.liuting.config.MainConfig;
import com.liuting.pojo.Person;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;



public class MainTest {

    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
//通过类型获取容器中的对象
        Person person01 = applicationContext.getBean(Person.class);
        Person person02 = (Person) applicationContext.getBean("person");
        System.out.println(person01);
        System.out.println(person02);
//通过getBeanDefinitionNames()方法可以获取容器中组件的所有名称
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (int i = 0; i < beanDefinitionNames.length; i++) {
            System.out.println(beanDefinitionNames[i]);
        }
    }
}

==============================测试结果(1===================
Person{name='lt', age='12'}
Person{name='lt', age='12'}


==============================测试结果(2===================
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
1.3.1 ComponentScan(s):注解扫描包设置,包扫描、只要标注了@Controller、@Service、@Repository、@Component,都会被自动扫描加入容器中

在这里插入图片描述

@Configuration
//注解扫描包设置
//excludeFilters = Filter[] 指定扫描的时候按照规则排除哪些规则
//includeFilters = Filter[] 指定扫描的时候只需要包含哪些组件
//useDefaultFilters 默认为true,加载所有组件
@ComponentScan(value = "com.liuting.*",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})})
public class MainConfig {
    @Bean
    @Scope()
    public Person person(){
        return new Person("lt","12");
    }
}

在这里插入图片描述
注意
在这里插入图片描述
在这里插入图片描述

package org.springframework.context.annotation;
//过滤类型
public enum FilterType {
    //注解
    ANNOTATION,
    //按照给定的类型
    ASSIGNABLE_TYPE,
    //使用ASPECTJ表达式(不太常用)
    ASPECTJ,
    //使用正则表达式
    REGEX,
    //使用自定义,实现TypeFilter
    CUSTOM;
    private FilterType() {
    }
}

package com.liuting.typeFilter;

import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class MyTypeFilter implements TypeFilter {
    /**
     * @param metadataReader the metadata reader for the target class  读取到当前正在扫描类信息
     * @param metadataReaderFactory a factory for obtaining metadata readers :获取到其他类的任何信息
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当前类注解信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前正在扫描到类的类信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //获取当前类资源(类路径)
        metadataReader.getResource();
        String className = classMetadata.getClassName();
        System.out.println("---->"+className);
        //true匹配成功,false匹配失败
        return false;
    }
}
1.3.2 Scope:默认是单实例的
* ConfigurableBeanFactory#SCOPE_PROTOTYPE  prototype   多实例
* ConfigurableBeanFactory#SCOPE_SINGLETON  singleton   单实例(默认值)
* org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST  request 同一次请求创建一个实例
* org.springframework.web.context.WebApplicationContext#SCOPE_SESSION  session 同一个session创建一个实例
1.3.3 @Lazy:
  • 单实例bean,默认在容器启动的时候创建对象
  • 懒加载:容器启动不创建对象,第一次使用(获取)Bean创建对象,并初始化
package com.liuting.config;

import com.liuting.pojo.Person;
import com.liuting.typeFilter.MyTypeFilter;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(value = "com.liuting.*",excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})})
@ComponentScan
public class MainConfig {
    @Bean
    @Lazy//第一次使用(获取)Bean创建对象,并初始化
    public Person person(){
        return new Person("lt","12");
    }
}

在这里插入图片描述

1.3.3 @Import:
/**
 * 给容器中注册组件:
 * 1) 包扫描+组件标注注解 (@Controller/@Service/@Repository/@Component)[自己写的]
 * 2) @Bean[导入的第三方包里面的组件],但是它比较麻烦(需要return等)
 * 3) @Import[快速给容器导入一个组件]
 */

二、生命周期

2.1-生命周期 @Bean指定初始化和销毁方法

在这里插入图片描述

#带init(),destroy()实体类
package com.liuting.pojo;


import org.springframework.stereotype.Repository;

@Repository
public class Person {
    public Person() {
        System.out.println("person...constructor");
    }

    public void init(){
        System.out.println("person.....init.....");
    }

    public void destroy(){
        System.out.println("person.....destroy.....");
    }
}

package com.liuting.config;

import com.liuting.pojo.Person;
import com.liuting.typeFilter.MyTypeFilter;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Repository;


@Configuration
@ComponentScan(value = "com.liuting.*",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Repository.class})},useDefaultFilters = false)
public class MainConfig {
    //将init()、destroy()设置到bean中
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Person person(){
       return new Person();
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

2.2-生命周期 InitializingBean和DisposableBean

package com.liuting.pojo;


import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Repository;

@Repository
public class Person implements InitializingBean, DisposableBean {
    public Person() {
        System.out.println("person...constructor");
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("person.....afterPropertiesSet.....");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("person.....destroy.....");
    }
}

在这里插入图片描述

2.3-生命周期 @PostConstrct和@PreDestroy

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

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

在这里插入图片描述

2.4-生命周期 BeanPostProcessor(后置处理器)

​ BeanPostProcessor【interface】,bean的后置处理器:

  •      在bean初始化前后进行一些处理工作:
    
  •      postProcessBeforeInitialization:在初始化之前工作
    
  •      postProcessAfterInitialization:在初始化之后工作
    

在这里插入图片描述

2.3-生命周期 @PostConstrct和@PreDestroy

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

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

[外链图片转存中…(img-JcmwRd0B-1611824474244)]

2.4-生命周期 BeanPostProcessor(后置处理器)

​ BeanPostProcessor【interface】,bean的后置处理器:

  •      在bean初始化前后进行一些处理工作:
    
  •      postProcessBeforeInitialization:在初始化之前工作
    
  •      postProcessAfterInitialization:在初始化之后工作
    

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值