Spring注解开发(详细标注)

配置类 相当于原先Spirng配置文件

@Configuration //加入Configuration注解
@ComponentScan(value=“要扫描的包名”) //扫描包 使注解生效
    //比如在Controller层上的Controller注解生效
public class MyConfig {
    						// 对象Id默认为方法名 
        					//获取到的对象默认是单例对象
        @Bean(“对象ID”	//可以用SCope注解来使单例对象变成多实例的
        @Scope("参数")	//参数:"prototype" 多实例,"singleton" 单实例(默认)
    public Person getPerson(){
        return new Person("123","18");
    }
}


@Component注解内部细节

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qH2lH7Jb-1642927486886)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122201002771.png)]

excludeFilters的具体使用[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oBpBJQOP-1642927486888)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122201253856.png)]

@ComponentScan注解可以多次使用 指定不同的 扫描策略

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VYfdJd47-1642927486889)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122201630049.png)]

public enum FilterType {


   ANNOTATION, //按照注解


   ASSIGNABLE_TYPE, //按照给定的类型	


   ASPECTJ,  //根据ASPECTJ 表达式


   REGEX, //根据正则表达式

 
   CUSTOM //自定义规则

}

定制过滤规则

​ *注意 要使用自定义过滤规则 要添加useDefaultFilters = false*[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4fvUlvCE-1642927486890)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122204345737.png)]

//实现TypeFilter接口重写 Match方法
public class MyTypeFilter implements TypeFilter {
    //确定此过滤器是否与给定元数据描述的类匹配。
//参数:
//metadataReader – 	目标类的元数据阅读器
//metadataReaderFactory – 为其他类(如超类和接口)获取元数据读取器的工厂
//返回值:
//		此过滤器是否匹配
//抛出:
//		IOException – 读取元数据时发生 I/O 故障
 
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取类注解信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取类所在的文件地址
        Resource resource = metadataReader.getResource();
        //类的信息
        ClassMetadata metadata = metadataReader.getClassMetadata();
        return false;
    }
}

​ **懒加载注解 : **

​ 单实例bean在容器启动时就创建了

​ 使用懒加载注解 可以使在容器启动时不创建bean 而在获取bean时在创建bean

@Bean //对象Id 默认为方法名
@Lazy  //懒加载
public Person getPerson(){
    System.out.println("创建");
    return new Person("123","18");
}

条件注解 @Conditional

@Coditional : 满足一定的条件才为容器中注册Bean

这个注解也可以标注在类上面

标注在类上面表示 必须满足某个条件 才会对类中的Bean进行注册

这是对类的统一设置

@Bean("person1")
//配置上Conditional
//value中放入自己的实现条件
@Conditional(value={MyContional.class})
public Person getPerson1(){
    return new Person("123","18");
}
//实现Condition接口   完成自定义配置
public class MyContional implements Condition {
    @Override
    //context 应用上下文环境
    //metadata 注解信息
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //获取当前对象工厂
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        //Bean的注册中心  可以查询注册了的Bean
        context.getRegistry();

        return context.getEnvironment().getProperty("os.name").contains("Linux");
    }
}

@Import注解:

​ 除了用Bean向容器中注册组件外还可以用**@Import注解**向容器中注册组件

​ 使用@Import注解注册的组件ID为类的全限定名

ComponentScan(value="com.atguigu")
@Import(Color.class) //@Import({多个类,逗号隔开})
public class MyConfig {

FactoryBean :

​ 向容器中注册Bean(与普通Bean不同) 注册为工厂Bean

//实现FactoryBean接口
public class MyFactoryBean implements FactoryBean<Color> {
    //获取工厂Bean
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
    //是否设置为单例模式
    //False:多实例  每次获取都会创建一个新的
    //True: 单实例  只会在容器中保存一份  每次从容器中拿取Bean
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}
@Bean
public MyFactoryBean getMyFactoryBean(){
    return new MyFactoryBean();
}

看似像容器注册的FactoryBean ,实际获取对象为Factory中getObject()方法返回的对象[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5X7FKmu2-1642927486891)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122221238775.png)]

可以在ID前面加一个&符号 获取原本的 工厂Bean

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maYY8O3E-1642927486891)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122221448490.png)]

Bean对象的生命周期

​ 生命周期: 对象的 创建 ----初始化 ------销毁的过程

​ 容器管理Bean的生命周期:

​ 我们可以自定义初始化和销毁方法,容器bean在进行到当前生命周期时i来调用我们自定义的初始化和销毁方法.

postProcessBeforeInitialization 在初始化之前工作 赋值之后 在 调用init方法之前

​ 初始化:

​ 对象的创建和构造:

​ 单实例:在容器初始化时就创建

​ 多实例:在第一个调用对象是创建

postProcessAfterInitialization 在初始化后工作

​ 销毁:

​ 单实例:在容器关闭时销毁

​ 多实例:IOC容器不会管理这个Bean 需要自己调用销毁方法

​ **1: **指定 init-method 和destroy-method

@Bean(initMethod = "init",destroyMethod = "destroy")
public Color getColor(){
    return new Color();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-niXusTHv-1642927486892)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122222900907.png)]

2 通过实现 initializingBean 和 DisposableBean 接口

public class Color implements InitializingBean, DisposableBean {
    //销毁时调用
    @Override
    public void destroy(){
        System.out.println("-----destory------");
    }
	//对象所有属性设置完以后调用
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
}

3: 可以使用JSR250

​ 使用@PostConstruct 在Bean初始化 属性赋值完成后调用初始化方法

​ @PreDestroy 在Bean销毁之前 调用销毁方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wI6Tehb6-1642927486893)(C:\Users\19637\AppData\Roaming\Typora\typora-user-images\image-20220122224534220.png)]

4: **BeanPostProcesser 接口(在这里 可以实现动态代理返回代理对象)

​ Bean的后置处理器

​ 在Bean的初始化前后调用

postProcessBeforeInitialization 在初始化之前工作 赋值之后  在 调用init方法之前
postProcessAfterInitialization	在初始化后工作 
//bean : 刚创建的对象
//beanName :刚创建的Bean名字
@Component
public class Processer implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization"+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization----------"+beanName);
        return bean;
    }
}

BeanPostProcesser使用原理

try {
    //给Bean属性赋值
    this.populateBean(beanName, mbd, instanceWrapper);
    //执行初始化
    exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}...................
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    ..................................
if (mbd == null || !mbd.isSynthetic()) {
    //应用BeanPostProcessorsBeforeInitialization方法
    //遍历容器中的所有BeanPostProcesser 挨个循环遍历BeanPostProcessorsBeforeInitialization 挨个执行,直到为空
    //如果BeanPostProcessorsBeforeInitialization 返回值为空将不会执行后续BeanPostProcessorsBeforeInitialization
    //方法
    wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}

try {
    //应用init方法
    this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
    throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}

if (mbd == null || !mbd.isSynthetic()) {
    //应用BeanPostProcessorsAfterInitialization方法
    wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

Spring底层对PostProcesser的使用:

​ Bean赋值, 注入其他组件@Autowired , 生命周期注解功能 @PreDestroy ,@Async,XXX BeanPostProcessser…

属性赋值
1 @Value
//使用@Value赋值
//括号里面可以写的东西
//1、基本数值
//2 、SPEL  SPring的表达式 。。#{}
//3 、也可以写 ....  ${} 取出配置文件的值
@Value("14")
private String name;
@Value("#{29-19}")
private String age;

2 @PropertySource 配合@Value使用

用法1…

//添加注解
@Component //注册成Bean
@PropertySource("classpath:person.properties")//引用配置文件
public class Person {
    //使用@Value赋值
    //1、基本数值
    //2 、SPEL  SPring的表达式 。。#{}
    //3 、也可以写 ....  ${} 取出配置文件的值 需要配合@PropertySource注解使用
    @Value("${person.name}")
    private String name;
    @Value("$person.age")
    private String age;

用法2…在配置类上加注解…

@PropertySource("classpath:person.properties") //在Config文件上添加@PropertySource注解才能使${}表达式生效
public class Config{

.................................

.}
3.自动装配(前提是在容器中存在对应属性的组件)

​ 1…@Autowired(requeired = false) : 根据属性类型去IOC容器中找组件自动装配(如果有多个相同类型的组件需要配合@Qualifier注解使用) 加上@Autowired的requeired=false 变成不是必须装配成功 可以不用装配;

​ 2…@Autowired+@Qualifier(“组件ID”) :根据名字和属性类型进行自动装配

​ 3…@Primary:让Spring进行自动装配置 时默认使用首选的Bean

	@Bean //对象Id 默认为方法名
    public Person getPerson(){
        return new Person("123","18");
    }
   @Bean
   @Primary //让这个Bean变成优选Bean  使用Autowired注入时  优先使用这个Bean
    public Person getPerson1(){
        return new Person();
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值