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该注解可以根据条件进行注入操作,作用类或者方法上面

自定义判断条件:此判断条件主要的作用是判断容器中是否存在studentbean,如果存在则注入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容器(下)的更多相关文章

  1. 三、spring成长之路——springIOC容器详解(上)

    目录 一.springIOC 一.springIOC 控制反转和依赖注入: ​ 简单的说就是将对象的创建,属性的的设置交给spring容器进行管理,而不再由用户自己创建,当用户需要使用该接口或者类的时 ...

  2. Spring学习总结三——SpringIOC容器三

    一:spring容器自动装配注入 为了减少xml中配置内容,可以使用自动装配注入,代替setter注入,只需要在 bean对象配置中添加属性autoWire即可,那么在类中就会自动扫描setXXX() ...

  3. Spring学习总结二——SpringIOC容器二

    一:指定bean的依赖关系 例如examplebean对象依赖examplebean1对象,那么在创建examplebean对象之前就 需要先创建examplebean1对象. 1:创建Example ...

  4. Spring学习总结一——SpringIOC容器一

    什么是spring spring是一个开源的轻量级的应用开发框架,它提供了IOC和AOP应用,可以减少组件之间的耦合度,即 解耦,spring容器可以创建对象并且管理对象之间的关系. 一:实例化spr ...

  5. Spring学习总结五——SpringIOC容器五

    一:spring组件扫描 可以使用注解的方式,代替在xml配置文件配置bean,可以减少配置文件的书写,只需要在spring容器配置 文件中配置<context:component-scan b ...

  6. 二·、spring成长之路——委派设计模式和单例设计模式

    3.委派设计模式 设计思想:就是多个类去完成一项的工作,其中一个类去分发任务,其他类做具体的任务,而具体表现是这个委派类的工作,具体过程是被委派类来操作的 [ITask.java]定义工作的统一标准 ...

  7. 物联网架构成长之路(45)-容器管理平台Rancher

    0.前言 按照上一篇博客,我已经把需要下载的rancher docker 依赖镜像下载上传到Harbor了. 1. 安装 执行如下,实现一键安装 docker run -d --restart=unl ...

  8. Spring - SpringIOC容器详解

    一.什么是Spring IOC: Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想. 在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是 ...

  9. SpringBoot下使用AspectJ(CTW)下不能注入SpringIOC容器中的Bean

    SpringBoot下使用AspectJ(CTW)下不能注入SpringIOC容器中的Bean 在SpringBoot中开发AspectJ时,使用CTW的方式来织入代码,由于采用这种形式,切面Bean ...

随机推荐

  1. jekyll开发静态网站

    一.Ruby环境安装配置 首先下载ruby安装ruby download ,安装完ruby后,再安装rubyGems:运行gem update --system即可. 然后下载DevKit-mingw ...

  2. php 函数func_get_args()、func_get_arg()与func_num_args()之间的区别

    php经常会有一些看似相近的函数,然而区别很大.[func_get_arg(),func_get_args(),func_num_args()]的区别,我们先看一下,下面的实例代码 从上面的结果中我们 ...

  3. pmp证书

  4. 使用mathjax在博客中完美显示数学公式,支持PC,手机浏览器

    在博客园的设置选项里 有页头HTML的框内输入: <script type="text/javascript" src="http://cdn.mathjax.or ...

  5. C# winfrom Datagridview表头样式和选中样式

    Griscolor是表格线的颜色 表头的样式修改如下图: 选中某一行的样色设置

  6. Asp.Net MVC 开发技巧(二)

    Linq查询 Linq的使用大体分为两种:语句表达式   和  方法 首先,我们要在控制器中定义好context private ApplicationDbContext db = new Appli ...

  7. find bugs设置

  8. 云端办公是 Office系统的未来方向么 ?

    云端办公是 Office系统的未来方向么 ? 话说随着互联网,HTML技术,云计算等技术的发展,越来越多的应用已经迁移到云端, 以我们熟悉的电脑游戏为例,从单机游戏,到网络游戏,再到网页游戏,基本就是 ...

  9. August 23rd 2017 Week 34th Wednesday

    Do not pray for easy lives. Pray to be stronger men. 不要祈祷舒适的生活,而是祈祷自己能变得更强大. It seems this quotation ...

  10. December 30th 2016 Week 53rd Friday

    Life without love is like a tree without blossoms or fruit. 缺少爱的生活就像从未开花结果的枯树. Love is not only the ...