目录
@Scope 声明实例范围
@PostConstruct 与 @PreDestroy
@ComponentScan 组件扫描
@Scope 声明实例范围
1、默认情况下 Spring 容器中的实例是单例的,即无论何时何地何人访问同一个地址,它们使用的都是同一个实例对象,可以使用 @scope 注解指定实例的范围。
2、@Scope 可以和 @Controller、@Service、@Repository、@Component、@Bean 等注解一起使用,指定实例交由 Spring 容器管理时,实例的使用范围。
3、@Scope 相当于以前配置文件中的:
4、下面提供一个控制层实例进行测试:
import com.fasterxml.jackson.databind.node.JsonNodeFactory;import com.fasterxml.jackson.databind.node.ObjectNode;import org.springframework.context.annotation.Scope;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Date;@RestController@RequestMapping("sys")/*** @Scope 指定实例范围:singleton、prototype、request、session、globalSession* 同理也可以用于其它的 @Controller、@Service、@Repository、@Component 等*/@Scope(value = "singleton")public class SystemController {private int id = 1;private static long count = 1;/*** http://localhost:8080/sys/get* @return*/@GetMapping("get")public String getTest() {JsonNodeFactory nodeFactory = JsonNodeFactory.instance;ObjectNode objectNode = nodeFactory.objectNode();objectNode.put("dateTime", new Date().toString());objectNode.put("id", id++);objectNode.put("count", count++);System.out.println(objectNode.toString());return objectNode.toString();}}
src/main/java/com/wmx/yuanyuan/controller/SystemController.java · 汪少棠/yuanyuan -
@PostConstruct 与 @PreDestroy
1、@PostConstruct 类似于 Serclet 的 inti() 方法,当 Bean 初始化时执行标记的方法。
2、@PreDestroy 类似于 Servlet 的 destroy() 方法,当 Bean 销毁时执行标记的方法。
3、下面以一个示例进行演示,提供一个 Spring 组件,交由 Spring 容器管理:
import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.node.JsonNodeFactory;import com.fasterxml.jackson.databind.node.ObjectNode;import org.ponent;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;import java.io.File;import java.io.IOException;import java.util.concurrent.atomic.AtomicLong;import static java.lang.System.getProperty;/*** 用一个组件来模拟记录一个网站被访问的总次数* 1)用户每访问一次,总次数就加1* 2)总次数可以存储在数据库,这里直接以文件的形式存储在磁盘上* 3)显然如果每次访问都读写磁盘,并不明智,这里刚好利用初始化与销毁这两个时机做缓存处理*/@Componentpublic class DataCacheComponent {//网站访问次数。使用原子类,高并发性能更好。private static AtomicLong numberOfVisits = new AtomicLong(0);//数据物理文件名称private static final String fileName = "f838e6f4-b35e-49b6-a38e-106fec99f387.json";/*** 应用启动,DataCacheComponent bean 初始化时执行以下操作:* 1、读取指定路径下的数据文件,不存在时创建* 2、如果数据文件已经存在,则继续读取其中的内容,并将值赋值给成员静态变量 numberOfVisits* 3、后续直接操作内存中的 numberOfVisits,提供性能,避免频繁操作磁盘** @throws IOException*/@PostConstructpublic void init() throws IOException {String java_home = getProperty("java.home");File temp_dir = new File(new File(java_home).getParent(), "temp");if (!temp_dir.exists()) {temp_dir.mkdirs();}File temp_file = new File(temp_dir, fileName);if (!temp_file.exists()) {temp_file.createNewFile();} else {ObjectMapper objectMapper = new ObjectMapper();JsonNode jsonNode = objectMapper.readTree(temp_file);if (jsonNode != null) {numberOfVisits.set(jsonNode.get("numberOfVisits").asLong());}}System.out.println("数据初始化完成:" + temp_file.getAbsolutePath() + ",numberOfVisits= " + this.numberOfVisits);}/*** 应用关闭,DataCacheComponent bean 销毁时执行以下操作:* 1、将内存中的 numberOfVisits 值持久化到磁盘文件** @throws IOException*/@PreDestroypublic void destroy() throws IOException {JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;ObjectNode objectNode = jsonNodeFactory.objectNode();objectNode.put("numberOfVisits", numberOfVisits.get());String java_home = getProperty("java.home");File temp_dir = new File(new File(java_home).getParent(), "temp");File temp_file = new File(temp_dir, fileName);ObjectMapper objectMapper = new ObjectMapper();objectMapper.writeValue(temp_file, objectNode);System.out.println("实例销毁,应用关闭,网站当前访问总次数:" + numberOfVisits.get());}//访问次数加1,用于其他地方调用public long numberOfVisitsAdd() {long l = DataCacheComponent.numberOfVisits.addAndGet(1L);System.out.println("网站当前访问总次数:" + l);return l;}}
4、提供一个控制层方法进程访问测试:
import com.ponent.DataCacheComponent;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestControllerpublic class VisitsController {@Resourceprivate DataCacheComponent dataCacheComponent;//http://localhost:8080/visitsTest@GetMapping("visitsTest")public String visitsTest() {return String.valueOf(dataCacheComponent.numberOfVisitsAdd());}}
@ComponentScan 组件扫描
1、与 @ComponentScan 注解相对应的XML配置是 <context:component-scan/>, 根据指定的配置自动扫描 package,将符合条件的组件加入到 IOC 容器中。
2、比如会将标识了 @Controller,@Service,@Repository,@Component 注解的类添加实例到 Spring 容器中;会将标识了 @Configuration 的类作为 Spring 配置类,当创建容器时会从该类加载注解。
3、对于 Spring Boot 项目,启动类会默认标记 @SpringBootApplication 注解,它的内部依赖了 @ComponentScan 注解:默认启动类同目录下(./**/*)任意子孙包中类上的注解都会被自动扫描,启动类上级目录下类中的注解默认是无法自动扫描到的(此时可以在启动类上自定义扫描路径:@ComponentScan(value = "com.wmx"))。
4、@ComponentScan 注解常用属性: