美文网首页
01. spring杂项

01. spring杂项

作者: 码农梦醒 | 来源:发表于2017-12-23 08:31 被阅读32次

    一. 我用spring做什么?

    • 对象依赖管理
    • 事务配置
    • 线程池管理
    • 缓存控制
    • 各种框架的整合
    • 切面编程
    • 配置注入

    二. Spring Bean的生命周期

    开始 --> 静态代码块 --> bean 构造方法 --> bean属性初始化 --> 
    BeanNameAware的setBeanName() --> BeanFactoryAware的setBeanFactory() --> 
    ApplicationContextAware的setApplicationContext() --> @PostConstruct 注解修饰的方法 
    --> InitializingBean的afterPropertiesSet() --> @PreDestroy修饰的方法 --> 结束
    

    测试代码详见:

    https://gitee.com/free_pan/spring-summary/tree/master/spring-complex-01

    部分代码节选:

    package com.pzy.spring_complex.bean;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.BeanFactoryAware;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    import lombok.extern.log4j.Log4j2;
    
    @Component
    @Log4j2
    public class Person
        implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
    
      static {
        log.debug("静态块初始化!");
      }
    
      @Value("${custom.name}")
      private String name;
    
      public Person() {
        log.debug("name: {}", name);
        log.debug("构造方法执行!");
      }
    
      @PostConstruct
      public void init() {
        log.debug("init");
      }
      
      @PreDestroy  
      public void preDestroy()  {  
          log.debug("执行InitAndDestroySeqBean: preDestroy");  
      }
    
      public String getName() {
        return name;
      }
    
      public void setName(String name) {
        log.debug("属性初始化!");
        this.name = name;
      }
    
      @Override
      public void setBeanName(String name) {
        log.debug("name: {}", this.name);
        log.debug("bean name: {}", name);
      }
    
      @Override
      public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.debug("bean factory: {}", beanFactory);
      }
    
      @Override
      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.debug("application context: {}", applicationContext);
      }
    
      @Override
      public void afterPropertiesSet() throws Exception {
        log.debug("afterPropertiesSet");
      }
    
      @Override
      public void destroy() throws Exception {
        log.debug("销毁");
      }
    
    }
    

    三. Spring Bean的作用域

    • Single: 在整个spring容器中, 有且始终只会产生一个Bean实例.
    • Prototype: 在每次显示的调用ApplicationContext.getBean方法时, 都会创建一个新实例
    • Request: 每个http请求一个实例
    • Session: 每个session一个实例

    注意点:

    1. Request, Session 范围的bean, 只有在直接使用到时, 才会去创建bean实例, 否则不会创建.
    2. Prototype 范围的bean, 只有在每次使用ApplicationContext.getBean()方法才会创建新的bean实例, 否则不会.

    代码详见:

    https://gitee.com/free_pan/spring-summary/tree/master/spring-complex-02

    四. Spring Bean的创建方式

    1. @Component 方式

    适用于自己编写的bean

    2. @Bean 方式

    适用于整合第三方bean

    五. yml文件属性注入

    注意: yml文件对于缩进非常敏感, 多一个空格或少一个空格,都有可能造成yml文件解析失败, 因此, 最好使用专用的yml文件编辑器, 让编辑器处理缩进问题.

    1. 普通属性注入
    2. boolean属性注入
    3. 集合属性注入
    4. Map属性注入
    5. 数组属性注入
    package com.pzy.spring_complex.bean;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    import lombok.Data;
    
    @Data
    @Component
    @ConfigurationProperties(prefix = "person")
    public class Person {
    
      private String name;
      private int age;
      private boolean sex;
      private List<String> hobbis = new ArrayList<>();
      private Map<String, Integer> map = new HashMap<>();
      private String[] arr;
    }
    
    server:
      port: 56000
    person:
      name: 张三
      age: 21
      sex: true
      hobbis:
      - test01
      - test02
      map:
        apple: 6
        orange: 7
      arr: one, two, three
    

    使用org.springframework.core.env.Environment获取yml的配置

    package com.pzy.spring_complex;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.core.env.Environment;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.alibaba.fastjson.JSON;
    import com.pzy.spring_complex.bean.Person;
    
    @SpringBootTest(classes = App.class)
    @RunWith(SpringJUnit4ClassRunner.class)
    public class AppTest {
    
      @Autowired
      private Person per;
      // 使用Environment获取yml的配置
      @Autowired
      private Environment env;
    
      @Test
      public void test_01() {
        System.out.println(JSON.toJSONString(per));
        // 使用Environment获取yml的配置
        System.out.println(env.getProperty("person.name"));
      }
    }
    
    

    spring注解的一个特殊的注入功能

    DemoService为接口,spring容器中有多个不同的DemoService实例

    // 会将所有DemoService的实例都放入demoServiceList中
    @Autowired
    private List<DemoService> demoServiceList;
    
    // 会将所有DemoService的实例都放入demoServiceMap中, key为bean的id值
    @Autowired
    private Map<String,DemoService> demoServiceMap;
    

    代码详见: https://gitee.com/free_pan/spring-summary/tree/master/spring-complex-03

    相关文章

      网友评论

          本文标题:01. spring杂项

          本文链接:https://www.haomeiwen.com/subject/xwcswxtx.html