JAVAEE颠覆者,SpringBoot实战一书学习小记(Bean的Scope,Bean的动态注入,Bean初始化和销毁)

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



猜你喜欢

转载自blog.csdn.net/jiulanhao/article/details/80926629