美文网首页
Spring boot Bean使用

Spring boot Bean使用

作者: 生活有方有圆 | 来源:发表于2019-02-17 19:56 被阅读0次

Bean的生命周期

165bd49d067394d6.png

Spring Ioc容器负责管理对象,包含创建、注入、销毁等。
程序员在使用的时候,可以通过相应的方法来获取想要的对象。

上图是Bean的生命周期,Bean是IOC管理的java对象。
相比于正常的对象生命周期,Bean的生命周期多出了几个重要环节。

Aware接口

获取Bean对象的一种方式
spring提供了各种Aware接口,咱们的bean只要实现了Aware接口,那么就可以获取相应的资源。

@Component
public class ApplicationContextProvide implements ApplicationContextAware {

    private ApplicationContext mApplicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        mApplicationContext = applicationContext;
    }
}
Aware接口和@AutoWired区别

@AutoWired是获取bean的基本方法,具体用法在实战部分
Aware接口是系统预先定义的

BeanPostProcessor接口

提供在Bean对象实例化完成后,对Bean的一次操作机会,是容器级别的。

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

当一个BeanPostProcessor实现类注册到IOC容器后,这个IOC容器创建的所有Bean都会执行BeanPostProcessor中定义的两种方法。

@Component
public class BeanPostProcess implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof ApplicationContextProvide) {
            ((ApplicationContextProvide) bean).init();
        }
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }
}

多个BeanPostProcessor的实现类可以用@Order注解来安排顺序
@Order注解是用在类上面的

bean初始化方法
  • 构造函数
  • 在指定方法上面实现@PostConstruct和@PostDestroy来指定
@Component
public class ApplicationContextProvide implements ApplicationContextAware {
    public String initObject;

    @PostConstruct
    public void init() {
        initObject = "start init";
    }
}
  • 实现InitializingBean接口,重写afterPropertiesSet方法
  • init-method 需要在配置文件中配置才能使用

上述方法按从上到下优先级由高到低。

总结

Bean被实例化后,会先把相关的依赖进行注入,这个时候一个完整的对象已经出来了。
接着BeanPostProcessor会遍历所有的对象,我们可以处理想要处理的对象,同时,spring也会查看每个bean对象是否被initAnnotationType/destroyAnnotationType注释,如果有的话,就把相应的方法加入到init/destroy队列中。
然后根据相应的作用域,判断何时产生bean。

Bean作用域

Bean的作用域由@Scope指定

  • 单例模式 Singleton
  • 原型 Prototype
  • 请求 request
  • 会话 session
  • globalsession

可以直接用@Scope("singleton")或者ConfigurableListableBeanFactory.SCOPE_SINGLETON

指定Scope的Bean

@Component
@Scope("prototype")
public class BeanScopeTest {

    public String beanName;
}

不同Scope的Bean的测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class BeanScopeTestTest {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private BeanScopeTest bean2;

    @Test
    public void testScope() {
        BeanScopeTest bean = applicationContext.getBean(BeanScopeTest.class);
        BeanScopeTest bean1 = applicationContext.getBean(BeanScopeTest.class);

        boolean isEquals = (bean == bean1);
        assertEquals(false, isEquals);
    }
}

Bean实战

spring 3.x的javaConfig项目,允许我们用注解的方式来定义Bean,但是也支持xml方式的配置,下面我们来试下Bean相关的注解。

注册bean

bean的配置分为三种

  • 自动配置
    需要搭配组件扫描@ComponentScan来发现需要自动注册的bean
    只需要在类上添加@Serviec @Controller @Repository @Component 等注解即可,其中@Component是没有特殊意义的bean的注册注解。
  • javaConfig显示配置
@Configuration
public class BeanConfigration {

    @Bean
    public BeanScopeTest getBeanConfig() {
        return new BeanScopeTest();
    }
}
  • xml配置

@Bean注解的扩展
相同类型的bean,指定不同的名字来区分对象

@Configuration
public class BeanConfigration {

    @Bean(name = "japanese")
    public User getJapanese() {
        User user = new User();
        user.name = "小日本";
        return user;
    }

    @Bean(name = "british")
    public User getBritish() {
        User user = new User();
        user.name = "英国人";
        return user;
    }
}

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class BeanConfigrationTest {

    @Resource(name = "japanese")
    private User japanese;

    @Resource(name = "british")
    private User british;

    @Test
    public void getBeanConfig() {
        assertEquals("小日本", japanese.name);
        assertEquals("英国人", british.name);
    }
}
使用bean

我们可以使用@AutoWired和@Resource来进行Bean的注入。
@AutoWired
@AutoWired是Spring自己的注解
@AutoWired是默认是根据类型来进行注入的,可以配合@Qualifier注解来指定名字进行注入
@AutoWired可以作用在属性、方法、构造函数上

@Resource
@Resource是JavaEE的注解
@Resource默认是根据名字来进行注入的
@Resource的装配顺序有兴趣的话可以自行查找

相关文章

网友评论

      本文标题:Spring boot Bean使用

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