Bean的Scope
每一个bean可以添加Scope标签来设置
个人理解从此看出Spring的控制反转默认一直都在用一个实例注入
1.Singleton 一个Spring容器中只有一个Bean的实例,此为Spring的默认配置,全容器共享一个实例。
2.Prototype 每次调用一个新建一个Bean的实例
3.Request Web项目中,给每一个http request 新建一个Bean实例。
4.Session Web项目中,给每一个http session新建一个Bean实例。
5.GlobalSession 这个只在portal应用中有用,给每一个global http session 新建一个实例。
可以拿小例子是演示一下默认的singleton 和 Prototype的结果
建立一个空的service,一个标注上@Scope("prototye") ,一个默认
@Service
@Scope("prototype")
public class DemoPrototypeService {
}
@Service
public class DemoSingletonService {
}
在config类加入扫描包注解
@Configuration
@ComponentScan("com.cn.sola.service")
public class SpringConfig {
}
然后用反射在测试类测试看结果
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootShiZhanApplicationTests {
@Test
public void contextLoads() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
DemoSingletonService d1 = context.getBean(DemoSingletonService.class);
DemoSingletonService d2 = context.getBean(DemoSingletonService.class);
System.out.println(d1.equals(d2));
DemoPrototypeService p1 = context.getBean(DemoPrototypeService.class);
DemoPrototypeService p2 = context.getBean(DemoPrototypeService.class);
System.out.println(p1.equals(p2));
}
}
结果就是DemoSingletonService结果为True,DemoPrototypeService为False。
由此看出Spring加Bean注解的都是一个实例。
Spring EL和资源的调用
未来的大牛
简单来说就是例如注解直接注入变量的值
首先为了方便先加入一个io工具依赖
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
然后可以在com.cn.sola包下建立一个test.properties,一个test.txt
比如test.properties里可以写
book.author=solatest
book.name=spring boot
txt可以写
未来的大牛
需要注入的bean(其中一个service)
package com.cn.sola.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
@Value("其他类的属性")
private String another;
public String getAnother() {
return another;
}
public void setAnother(String another) {
this.another = another;
}
}
另一个service
package com.cn.sola.service;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
@Service
public class SpringService {
//直接注入字符串
@Value("I Love You!")
private String normal;
//注入当前系统的操作环境(当前结果window10)
@Value("#{systemProperties['os.name']}")
private String osName;
//注入一个随机数
@Value("#{T(java.lang.Math).random()*100.0}")
private double randomNumber;
//注入demoService下String类型another参数的值
@Value("#{demoService.another}")
private String fromAnother;
//注入了一个文件类型
@Value("classpath:com/cn/sola/bean/test.txt")
private Resource testFile;
//暂时不明
@Value("http://www.baidu.com")
private Resource testUrl;
//注入了test.properties下book.name的值
@Value("${book.name}")
private String bookName;
//这类应该是可以直接获取properties的键值对
@Autowired
private Environment environment;
//不明
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigure(){
return new PropertySourcesPlaceholderConfigurer();
}
public void outputResource(){
try{
System.out.println(normal);
System.out.println(osName);
System.out.println(randomNumber);
System.out.println(fromAnother);
//commons-io依赖的方法
System.out.println(IOUtils.toString(testFile.getInputStream()));
System.out.println(IOUtils.toString(testUrl.getInputStream()));
System.out.println(bookName);
//用这个方法可以用key值获取到value,但是也要声明properties的位置@PropertySource("classpath:com/cn/sola/bean/test.properties")
System.out.println(environment.getProperty("book.author"));
}catch(Exception e){
e.printStackTrace();
}
}
}
配置类
package com.cn.sola.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("com.cn.sola.service")
@PropertySource("classpath:com/cn/sola/bean/test.properties")
public class ResourceConfig {
}
测试类
package com.cn.sola;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.cn.sola.config.ResourceConfig;
import com.cn.sola.service.SpringService;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootShiZhanApplicationTests {
@Test
public void contextLoads() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ResourceConfig.class);
SpringService service = context.getBean(SpringService.class);
service.outputResource();
context.close();
}
}
输出结果就和想象的一样啦------------
Bean的初始化和销毁
首先添加一个依赖,原文中用的JSR-250,现在只用这个就可以
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
我们实际开发的时候,经常会遇到在Bean在使用之前或者之后做些必要的操作,Spring对Bean的生命周期的操作提供了支持
有两种方式
(1)Java配置方式:使用@Bean的initMethod 和 destroyMethod例子 //这个在配置类里写
(2) 注解方式:需要添加依赖利用JSR-250的@PostConstruct和@PreDestroy //JSR-250现在已经包含在
使用@Bean形式的Bean 得在配置类里声明
package com.cn.sola.service;
public class BeanWayService {
public void init(){
System.out.println("@Bean-init-method");
}
public BeanWayService(){
super();
System.out.println("初始化构造函数-BeanWayService");
}
public void destroy(){
System.out.println("@Bean-destroy-method");
}
}
使用JSR250形式的Bean 在类里就可声明
package com.cn.sola.service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class JSR250WayService {
@PostConstruct
public void init(){
System.out.println("jsr250-init-method");
}
public JSR250WayService(){
super();
System.out.println("初始化构造参数-JSR250WayService");
}
@PreDestroy
public void destroy(){
System.out.println("jsr250-destory-method");
}
}
配置类 @Bean配置在此配置初始和销毁方法
package com.cn.sola.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.cn.sola.service.BeanWayService;
import com.cn.sola.service.JSR250WayService;
@Configuration
@ComponentScan("com.cn.sola.service")
public class ResourceConfig {
@Bean(initMethod="init",destroyMethod="destroy")//这里可以设置初始的调用方法
BeanWayService beanWayService(){
return new BeanWayService();
}
@Bean
JSR250WayService jsr250WayService(){
return new JSR250WayService();
}
}
下面是小测试类
package com.cn.sola;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.cn.sola.config.ResourceConfig;
import com.cn.sola.service.BeanWayService;
import com.cn.sola.service.JSR250WayService;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootShiZhanApplicationTests {
@Test
public void contextLoads() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ResourceConfig.class);
context.getBean(BeanWayService.class);
context.getBean(JSR250WayService.class);
context.close();
}
}
下面是结果
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.3.RELEASE)
2018-07-05 19:41:12.182 INFO 9204 --- [ main] c.c.s.SpringBootShiZhanApplicationTests : Starting SpringBootShiZhanApplicationTests on DESKTOP-LN7MO04 with PID 9204 (started by JAVA in D:\SpringBootWorkSpace\SpringBootShiZhan)
2018-07-05 19:41:12.184 INFO 9204 --- [ main] c.c.s.SpringBootShiZhanApplicationTests : No active profile set, falling back to default profiles: default
初始化构造函数-BeanWayService
@Bean-init-method
初始化构造参数-JSR250WayService
jsr250-init-method
2018-07-05 19:41:14.125 INFO 9204 --- [ main] c.c.s.SpringBootShiZhanApplicationTests : Started SpringBootShiZhanApplicationTests in 2.285 seconds (JVM running for 3.023)
2018-07-05 19:41:14.240 INFO 9204 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c20ffa8: startup date [Thu Jul 05 19:41:14 CST 2018]; root of context hierarchy
初始化构造函数-BeanWayService
@Bean-init-method
初始化构造参数-JSR250WayService
jsr250-init-method
2018-07-05 19:41:14.278 INFO 9204 --- [ main] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c20ffa8: startup date [Thu Jul 05 19:41:14 CST 2018]; root of context hierarchy
jsr250-destory-method
@Bean-destroy-method
jsr250-destory-method
@Bean-destroy-method