2.1 bean的范围
Singleton: 一个spring容器中只有一个bean实例,为spring 默认配置
Prototype: 每次调用新建一个bean的实例
Request: web项目中,每一个request创建一个实例 servlet 2.4以上有效
Session: web项目中,每个session创建一个实例 servlet 2.4以上有效
GlobalSession: 这个只在portal应用中有用,普通web项目同session范围一样。
2.2 spring的资源调用
常用的资源注入有以下几种:
(1)注入普通字符串
(2)注入操作系统属性
(3)注入表达式运算结果
(4)注入其他Bean属性
(5)注入文件内容
(6)注入网址内容
(7)注入属性文件
maven的pom文件如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>myproject</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.8.RELEASE</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.3</version> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> </project>
在classpath下新建文件config.properties内容如下:
user.name=jack user.age=13
使用到的bean
package com.antsoldier.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class DemonService { @Value("jack") private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
注入示例类
package com.antsoldier.config; 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; @Configuration @ComponentScan("com.antsoldier") @PropertySource("classpath:config.properties") public class DemonConfig { @Value("my name is jack") //外部的注入 private String normnal; @Value("#{systemProperties['os.name']}") //注入运行环境信息 private String osName; @Value("#{demonService.name}") //通过bean中的属性注入 private String name; @Value("classpath:config.properties") //注入外部文件 private Resource file; @Value("http://www.baidu.com") //注入url private Resource url; @Value("${user.name}") //通过加载配置文件注入用户名 特别注意前面是用$标示 private String userName; public void printResult() throws Exception{ System.out.println(normnal); System.out.println(osName); System.out.println(name); System.out.println(IOUtils.toString(file.getInputStream())); System.out.println(IOUtils.toString(url.getInputStream())); System.out.println(userName); } public String getNormnal() { return normnal; } public void setNormnal(String normnal) { this.normnal = normnal; } public String getOsName() { return osName; } public void setOsName(String osName) { this.osName = osName; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Resource getFile() { return file; } public void setFile(Resource file) { this.file = file; } public Resource getUrl() { return url; } public void setUrl(Resource url) { this.url = url; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
运行主类:
package com.antsoldier.config; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) throws Exception{ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemonConfig.class); DemonConfig dc = context.getBean(DemonConfig.class); dc.printResult(); } }
2.3 Bean的初始化和销毁
Bean的生命周期,即bean的初始化和销毁
两种方式:
(1)Java配置方式:使用bean的initMethod和destroyMethod方式
(2)注解方式:利用JSR-250的@PostConstruct和@PreDestory
修改maven pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.antsoldier.chapter01</groupId> <artifactId>springBoot</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <org.springframework-version>4.1.5.RELEASE</org.springframework-version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>jsr250-api</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.1</version> <configuration> <source>1.7</source> <target>1.7</target> <span style="color:#ff0000;"><encoding>UTF-8</encoding> </span> </configuration> </plugin> </plugins> </build> </project>
Java配置方式示例类如下:
package com.antsoldier.lifeCycle; public class BeanWayService { public void init(){ System.out.println("BeanWayService初始化"); } public BeanWayService(){ System.out.println("BeanWayService构造函数初始化"); } public void destory(){ System.out.println("BeanWayService结束"); } }
注解方式示例类如下:
package com.antsoldier.lifeCycle; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class JSR250WayService { @PostConstruct public void init(){ System.out.println("jsr250 初始化"); } public JSR250WayService(){ System.out.println("jsr250构造函数初始化"); } @PreDestroy public void destory(){ System.out.println("jsr250销毁"); } }
配置类如下:
package com.antsoldier.lifeCycle; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.antsoldier.lifeCycle") public class LifeCycleConfig { @Bean(initMethod="init",destroyMethod="destory") BeanWayService beanWayService(){ return new BeanWayService(); } @Bean JSR250WayService jsr250WayService(){ return new JSR250WayService(); } }
主类如下:
package com.antsoldier.lifeCycle; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) throws InterruptedException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(LifeCycleConfig.class); context.getBean(BeanWayService.class); context.getBean(JSR250WayService.class); context.close(); } }
运行结果如下:
四月 24, 2017 9:41:38 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3499c4cc: startup date [Mon Apr 24 21:41:38 CST 2017]; root of context hierarchy BeanWayService构造函数初始化 BeanWayService初始化 jsr250构造函数初始化 jsr250 初始化 四月 24, 2017 9:41:38 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3499c4cc: startup date [Mon Apr 24 21:41:38 CST 2017]; root of context hierarchy jsr250销毁 BeanWayService结束
2.4 配置不同环境下使用不同配置的情况
(1)通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境,在开发中使用@Profile注解类或者方法,达到在不同情况下实例化不同的bean
(2)通过设定jvm的spring.profiles.active参数来设置配置环境
(3)web项目设置在servlet的context parameter
此处主要那第一种情况进行示例:
示例Bean:
package com.antsoldier.profile; public class DemoBean { private String content; public DemoBean() { } public DemoBean(String content) { super(); System.out.println(content); this.content = content; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
主配置类:
package com.antsoldier.profile; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration public class ProfileConfig { @Bean @Profile("dev") public DemoBean devDemoBean(){ return new DemoBean("开发者模式"); } @Bean @Profile("prod") public DemoBean prodDemoBean(){ return new DemoBean("生产模式"); } }
运行类
package com.antsoldier.profile; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { // AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(ProfileConfig.class); // acac.getEnvironment().setActiveProfiles("dev"); // System.out.println(acac.getBean(DemoBean.class).getContent()); // acac.close(); // AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(); acac.getEnvironment().setActiveProfiles("prod"); acac.register(ProfileConfig.class); acac.refresh(); acac.close(); } }
运行结果如下:
四月 24, 2017 10:11:02 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@257db177: startup date [Mon Apr 24 22:11:02 CST 2017]; root of context hierarchy 生产模式 四月 24, 2017 10:11:02 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@257db177: startup date [Mon Apr 24 22:11:02 CST 2017]; root of context hierarchy
注意上面注释掉的部分是错误的写法,会报如下异常:
四月 24, 2017 10:14:13 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@799ac2e3: startup date [Mon Apr 24 22:14:13 CST 2017]; root of context hierarchy Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.antsoldier.profile.DemoBean] is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968) at com.antsoldier.profile.Main.main(Main.java:10)
2.5 事件监听
spring的事件监听功能
Spring的事件需要遵循如下流程:
(1)自定义事件,集成ApplicationEvent
(2)定义事件监听器
(3)使用容器发布事件
自定义事件如下:
package com.antsoldier.event; import org.springframework.context.ApplicationEvent; /** * 自定义事件 * @author Administrator * */ public class DemoEvent extends ApplicationEvent{ private String msg; public DemoEvent(Object source,String msg) { super(source); this.msg = msg; } public String say(){ return msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
自定义事件监听器:
package com.antsoldier.event; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * 事件监听者 * @author Administrator * */ @Component public class DemoListener implements ApplicationListener<DemoEvent>{ @Override public void onApplicationEvent(DemoEvent event) { //用于执行监听事件 System.out.println("监听事件被触发:" + event.say()); } }
事件发布器:
package com.antsoldier.event; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; /** * 事件发布者 * @author Administrator * */ @Component public class DemoPublisher{ @Autowired ApplicationContext applicationContext; public void publish(){ applicationContext.publishEvent(new DemoEvent(this, "时间发布")); } }
主配置类:
package com.antsoldier.event; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.antsoldier.event") public class Config { }
运行主类
package com.antsoldier.event; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class); DemoPublisher dp = annotationConfigApplicationContext.getBean(DemoPublisher.class); dp.publish(); annotationConfigApplicationContext.close(); } }