四、spring成长之路——springIOC容器(下)
5.spring注解开发(Spring扩展知识)
5.1定义配置类:@Configuration
声明一个类为IOC容器 @Bean
定义一个Bean
package com.itcloud.annotation;
import com.itcloud.pojo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CommonConfig {
@Bean
public Student student(){
Student student = new Student();
student.setId(10l);
student.setName("configuration");
return student;
}
}
测试
package com.itcloud.pojo.anntation;
import com.itcloud.annotation.CommonConfig;
import com.itcloud.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnotationTest {
ApplicationContext context = new AnnotationConfigApplicationContext(CommonConfig.class);
@Test
public void testAnnotation(){
Student stu = context.getBean(Student.class);
}
}
注解@ComponmentScan
使用详解,该注解作用在类上面
@ComponentScan(value = "com.itcloud",useDefaultFilters = false,includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {
Component.class, Service.class, Repository.class
})
},excludeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION,classes = {
Controller.class
})
})
bean的作用域,@Scope
定义在方法上面
/**
* 取值:singleton:默认值,单实例,容器加载的时候进行bean的创建
* prototype:允许创建多个对象,使用的时候进行队形的创建
*/
@Scope(value = "")
bean的懒加载,@Lazy
放在方法上面,在没有这个注解的时候,bean会在容器启动的时候进行加载,但是这个注解使用之后,当使用到这个bean的时候才会进行性bean的加载。
5.2.按照条件进行注入
@Conditional
该注解可以根据条件进行注入操作,作用类或者方法上面
自定义判断条件:此判断条件主要的作用是判断容器中是否存在student
bean,如果存在则注入teacher,否则不注入;
package com.itcloud.annotation.conditional;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class MyConditional implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
BeanDefinitionRegistry registry = context.getRegistry();
boolean student = registry.containsBeanDefinition("student");
if(student){
return true;
}
return false;
}
}
@Bean("teacher")
@Conditional({MyConditional.class})
public Teacher teacher(){
Teacher t = new Teacher();
t.setId(10l);
t.setName("李老师");
return t;
}
5.3.@Import注解进行注入
具体用法:按照注解的意思我们可以导入一个ioc
容器,ImportSelector
或者ImportBeanDefinitionRegistrar
的子类,再或者是一个普通的组件类,即被@Component
相关注解修饰的类,那么普通的类可以吗?
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
//在这之前我们自定义了一个Color类
@Configuration
@Import({Color.class})
public class CommonConfig {...}
经过测试普通类也是可以导入的,但是普通类的bean默认的value是全类名:com.itcloud.annotation.vo.Color
ImportSelector测试
自定义一个MyImportSelector.java类实现ImportSelector
接口,把需要导入的类通过字符串数组的形式进行返回,一定要是全类名
参数AnnotationMetadata
可以获取IOC容器上面的注解
package com.itcloud.annotation.myimport;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.itcloud.annotation.vo.Blue","com.itcloud.annotation.vo.Red"};
}
}
ImportBeanDefinitionRegistrar测试
package com.itcloud.annotation.myimport;
import com.itcloud.annotation.vo.Yellow;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//这里可以进行bean的注册
RootBeanDefinition beanDefinition = new RootBeanDefinition(Yellow.class);
registry.registerBeanDefinition("yellow", beanDefinition);
}
}
5.4、FactoryBean注入
在2>2.7里面已经说过了,此处不再赘述:点击跳转
bean的生命周期,在注解中的表现如下:
和xml配置文件相似;
@Bean(value = "student",initMethod = "init",destroyMethod = "destory")
5.5、后置处理详解
1.注解:@PostConstruct
和 @PreDestory
在这里一定要将此类注入到容器中,至于怎么注入,就不再赘述
package com.itcloud.annotation.vo;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class PostBean {
public PostBean(){
System.out.println("构造方法执行.....");
}
@PostConstruct
public void postConstruct(){
System.out.println("postConstruct......");
}
@PreDestroy
public void destroy(){
System.out.println("容器关闭之前执行的吗......");
}
}
测试结果:
<!--
构造方法执行.....
postConstruct......
## 容器关闭之前执行如下
容器关闭之前执行的吗......
-->
2.两个接口 InitializingBean
DisposableBean
package com.itcloud.annotation.vo;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class PostProcessorBean implements InitializingBean, DisposableBean {
public PostProcessorBean(){
System.out.println("PostProcessorBean.....构造方法执行");
}
@Override
public void destroy() throws Exception {
System.out.println("PostProcessorBean.......destroy()");
}
//属性设置完成之后执行,构造方法之后调用
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("PostProcessorBean.......afterPropertiesSet()");
}
}
3.BeanPostProcessor
原理解析
在前面后置处理器中我们已经了解了,通过实现接口BeanPostProcessor
可以进行后置处理,在这里我们将要对后置处理原理进行简单的介绍
定义一个后置处理器
这个处理器会在所有bean创建的时候,构造方法之后执行,所有初始化方法之前执行,而方法postProcessAfterInitialization
会在初始化之后调用,不需要容器关闭
package com.itcloud.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before*****beanName = " + beanName +"-----bean = " + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("After*****beanName = " + beanName +"----bean = " + bean);
return bean;
}
}
package com.itcloud.processor;
import com.itcloud.annotation.vo.Color;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Component;
@Configuration
@ComponentScan(useDefaultFilters = false, includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
Component.class
})
})
public class ProcessorConfig {
@Bean
public Color color(){
return new Color();
}
}
源码解析:
5.6、属性赋值和自动装配
1.@Value的使用
package com.itcloud.annotation.vo;
import org.springframework.beans.factory.annotation.Value;
public class Color {
//直接赋值
@Value("red")
private String type;
//EL表达式
@Value("#{100.30-13.43}")
private Double length;
//引用外部属性文件
@Value("${value.username}")
private String username;
@Value("${value.password}")
private String password;
}
在配置类上面一定要引用外部文件,通过注解@PropertySource
package com.itcloud.processor;
import com.itcloud.annotation.vo.Color;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Component;
@Configuration
@ComponentScan(useDefaultFilters = false, includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
Component.class
})
})
@PropertySource("classpath:/properties/value.properties")
public class ProcessorConfig {
@Bean
public Color color(){
return new Color();
}
}
通过环境变量来获取属性的值
Environment environment = context.getEnvironment();
String property = environment.getProperty("value.username");
2.自动装配使用的注解
2.1、spring注解:@Autowired前面我们已经说过,这个注解可以配合@Qualifier使用,明确调用使用特定的Bean
@Autowired也可以配置@Primary注解使用,当类型相同的使用,会优先选择@Primary注解标识的 bean
2.2.非spring注解:@Resource按照名称注入,@Inject,@Autowired用法类似,需要引入jar:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
5.6.在类中使用spring底层的组件
如果一个类想要使用spring底层的组件,可以实现一些接口xxxAware
,这个接口都是org.springframework.beans.factory.Aware
接口的子类
1.xxxAware
方法的使用
package com.itcloud.annotation.vo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.*;
import org.springframework.core.env.Environment;
import org.springframework.util.StringValueResolver;
public class Color implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
private ApplicationContext context;
public void userContext(){
Environment environment = this.context.getEnvironment();
String property = environment.getProperty("value.url");
System.out.println(property);
}
//获取applicationContext对象
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
//获取当前bean的name
@Override
public void setBeanName(String name) {
System.out.println("name===" + name);
}
//进行字符串的解析
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
String result = resolver.resolveStringValue("数据库的名称:${value.username}, el表达式解析:#{10-3*3}");
System.out.println(result);
}
}
5.6.@Profile的使用
此注解既可以使用在bean上,也可以定义在一个IOC容器上面,激活的方式:
1.类激活
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
ctx.refresh();
2.jvm参数激活:
-Dspring.profiles.active="profile1,profile2"
四、spring成长之路——springIOC容器(下)的更多相关文章
- 三、spring成长之路——springIOC容器详解(上)
目录 一.springIOC 一.springIOC 控制反转和依赖注入: 简单的说就是将对象的创建,属性的的设置交给spring容器进行管理,而不再由用户自己创建,当用户需要使用该接口或者类的时 ...
- Spring学习总结三——SpringIOC容器三
一:spring容器自动装配注入 为了减少xml中配置内容,可以使用自动装配注入,代替setter注入,只需要在 bean对象配置中添加属性autoWire即可,那么在类中就会自动扫描setXXX() ...
- Spring学习总结二——SpringIOC容器二
一:指定bean的依赖关系 例如examplebean对象依赖examplebean1对象,那么在创建examplebean对象之前就 需要先创建examplebean1对象. 1:创建Example ...
- Spring学习总结一——SpringIOC容器一
什么是spring spring是一个开源的轻量级的应用开发框架,它提供了IOC和AOP应用,可以减少组件之间的耦合度,即 解耦,spring容器可以创建对象并且管理对象之间的关系. 一:实例化spr ...
- Spring学习总结五——SpringIOC容器五
一:spring组件扫描 可以使用注解的方式,代替在xml配置文件配置bean,可以减少配置文件的书写,只需要在spring容器配置 文件中配置<context:component-scan b ...
- 二·、spring成长之路——委派设计模式和单例设计模式
3.委派设计模式 设计思想:就是多个类去完成一项的工作,其中一个类去分发任务,其他类做具体的任务,而具体表现是这个委派类的工作,具体过程是被委派类来操作的 [ITask.java]定义工作的统一标准 ...
- 物联网架构成长之路(45)-容器管理平台Rancher
0.前言 按照上一篇博客,我已经把需要下载的rancher docker 依赖镜像下载上传到Harbor了. 1. 安装 执行如下,实现一键安装 docker run -d --restart=unl ...
- Spring - SpringIOC容器详解
一.什么是Spring IOC: Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想. 在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是 ...
- SpringBoot下使用AspectJ(CTW)下不能注入SpringIOC容器中的Bean
SpringBoot下使用AspectJ(CTW)下不能注入SpringIOC容器中的Bean 在SpringBoot中开发AspectJ时,使用CTW的方式来织入代码,由于采用这种形式,切面Bean ...
随机推荐
- 基于Vue的WebApp项目开发(六)
实现商品购买列表页面 步骤一:新建goodslist.vue文件 <template> <div id="tml"> <!--利用mui中的图文表格组 ...
- 深入理解HashMap和concurrentHashMap
原文链接:https://segmentfault.com/a/1190000015726870 前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇 ...
- “互联网+”背景下使用微信公众号增强班主任工作与整合教学资源(泰微课)
前记:此文是我爱人一项作业.因为我本人对于微信这一块比较熟悉,就参与这项作业中.此文已经参加移动和教育相关活动.作者是我爱人,如有转载请署名作者. 一.什么是"互联网+"? 早在1 ...
- 通过Windows Server 2008 R2建立iSCSI存储
名词解释:iSCSI技术是一种由IBM公司研究开发的,是一个供硬件设备使用的可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行 SCSI协议,使其能够在诸如高速千兆以太网上 ...
- Ubuntu 14.04 下安装Skype
操作1: Ubuntu 14.04 下安装Skype,使用 Ctr+Alt+T组合键打开终端Terminal,输入如下即可: wget -O skype.deb http://download.sky ...
- HDFS 读取、写入、遍历文件夹获取文件全路径、append
版权声明:本文为博主原创文章,未经博主同意不得转载.安金龙 的博客. https://blog.csdn.net/smile0198/article/details/37573081 1.从HDFS中 ...
- 【[HAOI2015]树上染色】
这道题真是非常神仙 第一眼看到题面肯定能想到状态是\(dp[i][j]\)表示\(i\)这棵子树里染了\(j\)个黑点的最大值 最大值? 什么最大值,之后就会发现这个样子完全没有办法转移 所以我们考虑 ...
- [19/04/29-星期一] GOF23_行为型模式(责任链模式、迭代器模式)
一.行为模式 二.责任链模式(chainOfResponsibility) [一个请求类] /*** 请假类 * 封装请假的基本信息 */ package cn.sxt.chainOfResponsi ...
- Kali-linux创建密码字典
所谓的密码字典主要是配合密码破解软件所使用,密码字典里包括许多人们习惯性设置的密码.这样可以提高密码破解软件的密码破解成功率和命中率,缩短密码破解的时间.当然,如果一个人密码设置没有规律或很复杂,未包 ...
- leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
1.2的幂 正确写法: class Solution { public: bool isPowerOfTwo(int n) { ) return false; )) == ; } }; 错误写法1: ...