1Java元注解
@Retention:注解的保留位置
- @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
- @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
- @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target:注解的作用目标
- @Target(ElementType.TYPE) //接口、类、枚举、注解
- @Target(ElementType.FIELD) //字段、枚举的常量
- @Target(ElementType.METHOD) //方法
- @Target(ElementType.PARAMETER) //方法参数
- @Target(ElementType.CONSTRUCTOR) //构造函数
- @Target(ElementType.LOCAL_VARIABLE)//局部变量
- @Target(ElementType.ANNOTATION_TYPE)//注解
- @Target(ElementType.PACKAGE) ///包
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
2@Scope
描述容器如何创建Bean:
- Singleton:一个容器只有一个Bean实例,Spring的默认配置
- Prototype:每次调用新建一个Bean实例
- Request:每个http request新建一个Bean实例
- Session:每个http session新建一个Bean实例
- GlobalSession:这个使用在portal应用中,给每个global http session新建一个Bean实例
默认(Singleton)和prototype样例:
@Service
public class DemoSingletonService {
}
@Service
@Scope("prototype")
public class DemoPrototypeService {
}
效验:
package com.study.spring.spring5.config.scope;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
@Configuration
@ComponentScan("com.study.spring.spring5.config.scope")
public class ScopeApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeApp.class);
DemoSingletonService demoSingletonServiceFirst = context.getBean(DemoSingletonService.class);
DemoSingletonService demoSingletonServiceSecond = context.getBean(DemoSingletonService.class);
DemoPrototypeService demoPrototypeServiceFirst = context.getBean(DemoPrototypeService.class);
DemoPrototypeService demoPrototypeServiceSecond = context.getBean(DemoPrototypeService.class);
System.out.println("DemoSingletonService 前后两次获得对象是否相同:"+demoSingletonServiceFirst.equals(demoSingletonServiceSecond));
System.out.println("DemoPrototypeService 前后两次获得对象是否相同:"+demoPrototypeServiceFirst.equals(demoPrototypeServiceSecond));
context.close();
}
}
结果:
DemoSingletonService 前后两次获得对象是否相同:true
DemoPrototypeService 前后两次获得对象是否相同:false
3Spring EL和资源注入
演示:
pom添加文件操作库
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
配置类:
package com.study.spring.spring5.config.el;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.Resource;
/**
* EL配置类
* @author chaozai
* @date 2018年9月6日
*
*/
@Configuration
@ComponentScan("com.study.spring.spring5.config.el")
@PropertySource("classpath:config/el.properties")
public class ElConfig {
/**
* 注入SystemProperties内属性
*/
@Value("#{systemProperties['os.name']}")
private String osName;
/**
* 注入表达式结果
*/
@Value("#{T(java.lang.Math).random()*100.0}")
private double randomNumber;
/**
* 注入其他Bean内属性
*/
@Value("#{someConfig.message}")
private String otherObjMessage;
/**
* 注入文件资源
*/
@Value("classpath:config/el.properties")
private Resource testFile;
/**
* 注入网站资源
*/
@Value("https://blog.csdn.net/qqchaozai")
private Resource testUrl;
/**
* 注入配置文件
*/
@Value("${code.author}")
private String codeAuthor;
// /**
// * 注入配置文件--两种方式冲突,会因两次加载而触发异常
// */
// @Autowired
// private Environment environment;
//
// /**
// * 注入配置文件
// */
// @Bean
// public static PropertyPlaceholderConfigurer propertyConfigure() {
// return new PropertyPlaceholderConfigurer();
// }
public void outputResource() {
try {
System.out.println(osName);
System.out.println("------------------------------------------------------------");
System.out.println(randomNumber);
System.out.println("------------------------------------------------------------");
System.out.println(otherObjMessage);
System.out.println("------------------------------------------------------------");
System.out.println(IOUtils.toString(testFile.getInputStream(), Charset.forName("UTF-8")));
System.out.println("------------------------------------------------------------");
System.out.println(IOUtils.toString(testUrl.getInputStream(), Charset.forName("UTF-8")).substring(0, 100));
System.out.println("------------------------------------------------------------");
System.out.println(codeAuthor);
// System.out.println(environment.getProperty("code.author"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.study.spring.spring5.config.el;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
@Component
public class SomeConfig {
/**
* 注入字符串
*/
@Value("SomeConfig-message")
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
验证:
package com.study.spring.spring5.config.el;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
public class ElApp {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class);
ElConfig elConfig = context.getBean(ElConfig.class);
elConfig.outputResource();
context.close();
}
}
结果:
Windows 7
------------------------------------------------------------
0.39485181937940483
------------------------------------------------------------
SomeConfig-message
------------------------------------------------------------
code.author:chaozai
------------------------------------------------------------
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<link rel="canonical" href
------------------------------------------------------------
chaozai
4Bean的初始化和销毁
两种方式:
- Java配置:@Bean添加属性initMethod和destroyMethod
- 注解方式:JSR-250中@PostConstruct和@PreDestroy
pom添加依赖:
<!-- https://mvnrepository.com/artifact/javax.annotation/jsr250-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
java配置:
package com.study.spring.spring5.config.initdestroy;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
public class BeanWayService {
public BeanWayService() {
super();
System.out.println("BeanWayService bean create");
}
public void init(){
System.out.println("BeanWayService init method");
}
public void destroy(){
System.out.println("BeanWayService destory method");
}
}
注解方式:
package com.study.spring.spring5.config.initdestroy;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
public class JSR250WayService {
public JSR250WayService() {
super();
System.out.println("JSR250WayService bean create");
}
@PostConstruct
public void init(){
System.out.println("JSR250WayService init method");
}
@PreDestroy
public void destory(){
System.out.println("JSR250WayService destory method");
}
}
验证:
package com.study.spring.spring5.config.initdestroy;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
@Configuration
@ComponentScan("com.study.spring.spring5.config.initdestroy")
public class InitDestroyApp {
@Bean(initMethod="init",destroyMethod="destroy")
BeanWayService beanWayService(){
return new BeanWayService();
}
@Bean
JSR250WayService jSR250WayService(){
return new JSR250WayService();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(InitDestroyApp.class);
context.getBean(BeanWayService.class);
context.getBean(JSR250WayService.class);
context.close();
}
}
结果:
BeanWayService bean create
BeanWayService init method
JSR250WayService bean create
JSR250WayService init method
JSR250WayService destory method
BeanWayService destory method
5Profile
为不同环境应用不同配置提供支持
样例:
package com.study.spring.spring5.config.profile;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
public class DemoBean {
public DemoBean(String type) {
System.out.println("type:"+type);
}
}
package com.study.spring.spring5.config.profile;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/**
*
* @author chaozai
* @date 2018年9月6日
*
*/
@Configuration
@ComponentScan("com.study.spring.spring5.config.profile")
public class ProfileApp {
@Bean
@Profile("prod")
DemoBean prodDemoBean(){
return new DemoBean("product");
}
@Bean
@Profile("dev")
DemoBean devDemoBean(){
return new DemoBean("develop");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("prod");
context.register(ProfileApp.class);
context.refresh();
context.getBean(DemoBean.class);
context.close();
context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("dev");
context.register(ProfileApp.class);
context.refresh();
context.getBean(DemoBean.class);
context.close();
}
}
结果:
type:product
type:develop
6事件(Application Event)
自定义事件:
package com.study.spring.spring5.config.event;
import org.springframework.context.ApplicationEvent;
/**
* 自定义事件
* @author chaozai
* @date 2018年9月6日
*
*/
public class DemoEvent extends ApplicationEvent{
private static final long serialVersionUID = -1404313071348144822L;
private String msg;
public DemoEvent(Object source,String msg) {
super(source);
this.msg = msg;
}
public String getMsg(){
return msg;
}
public void setMsg(String msg){
this.msg = msg;
}
}
自定义事件监听器:
package com.study.spring.spring5.config.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 自定义事件监听器
* @author chaozai
* @date 2018年9月6日
*
*/
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
@Override
public void onApplicationEvent(DemoEvent event) {
String msg = event.getMsg();
System.out.println("receive msg from publisher,msg info:"+msg);
}
}
事件发布者:
package com.study.spring.spring5.config.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
/**
* 事件发布者
* @author chaozai
* @date 2018年9月6日
*
*/
@Component
public class DemoPublisher {
@Autowired
ApplicationContext context;
/**
* 推送消息
* @param msg
*/
public void publishMsg(String msg){
context.publishEvent(new DemoEvent(this, msg));
}
}
验证:
package com.study.spring.spring5.config.event;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 测试Spring事件监听
* @author chaozai
* @date 2018年9月6日
*
*/
@Configuration
@ComponentScan("com.study.spring.spring5.config.event")
public class EventApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventApp.class);
context.getBean(DemoPublisher.class).publishMsg("hello application event!");
context.close();
}
}
结果:
receive msg from publisher,msg info:hello application event!
爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!