深入理解Spring —— 控制Bean 的创建时机

如何控制Bean的创建

通过上篇文章http://blog.csdn.net/qq_23980427/article/details/80888040,我们知道了Spring Boot 中一个@Controller修饰的Bean是在什么时间被创建的,那么这个Bean创建时间能不能由我们管控?答案是肯定的

创建时机

我们知道Spring 中Bean都是由ApplicationContext这个容器来管控的,上一篇中,我们可以看到的结果是,在程序启动的时候,我们用@Controller 修改的Bean就被创建。那么我们可以想一想,如果我的程序到最后都没有用到这个Controller,那这个Controller 是不是就有点占用资源了。这个时候我们应该想到的就是懒加载<不知道懒加载是什么的同学自行百度哈~>。Spirng给我们提供了懒加载的配置。

首先我们来看一下默认加载

Spring Boot的启动方法
run()——>refreshContext()———->refresh() 中的finishBeanFactoryInitialization
有如下注释:

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

实例化非懒加载单例,(参考上一篇 地址文件头)我们可以得出结论,默认Bean的配置是non-lazy-init的

如何配置懒加载呢?
一个很简单方式 @Lazy 注解,改注解可以在类上和方法上添加,配置普通的@Bean的时候也可以加上改注解,实现Bean对象的懒加载

@Controller
@Lazy
@RequestMapping("/test")
public class TestController {
    public TestController(){
        System.out.println("TestController 创建了");
    }

    @GetMapping
    @ResponseBody
    public String getTest(){
        return "aaa";
    }
}

通过控制台我们可以看到,创建的TestController 的时机是在访问这个Controller的时候。

2018-07-03 16:11:49.224  INFO 844 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8888 (http)
2018-07-03 16:11:49.229  INFO 844 --- [           main] com.seven.App                            : Started App in 4.073 seconds (JVM running for 4.575)
2018-07-03 16:11:49.311  INFO 844 --- [nio-8888-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-07-03 16:11:49.311  INFO 844 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2018-07-03 16:11:49.389  INFO 844 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 78 ms
TestController 创建了

开发中碰到的问题

这边给大家提一个问题,有开发经验的同学在一般的web项目中会分三层,Controller Service Dao,在Controller 中,我们经常会这样写:
Controller层

@Controller
//@Lazy
@RequestMapping("/test")
public class TestController {

    @Autowired
    private ITestService testService;

    public TestController(){
        System.out.println("TestController 创建了");
    }

    @GetMapping
    @ResponseBody
    public String getTest(){
        return "aaa";
    }
}

Service 层

//@Service
public class TestService implements ITestService {
}

有时候我们忘记了在Service 的实现类上面加@Service注解,启动的时候,会报错,你知道报的错是什么吗?如果在Controller上面加上@Lazy注解,会在访问Controller 的时候报错。 如果看到这里你还不知道答案的话,建议再把上面一节看一下。这里就不细说了,留给各位童鞋一点思考的空间。

总结

  1. 创建Bean的时机有两种选择
    一. 采用默认的方式,不加额外的配置,在启动程序的时候加载并创建好
    二. 通过设置懒加载(non-lazy-init) @Lazy 注解

问题

容器管控的Bean在创建的时候,不管是lazy-init还是non-lazy-init 默认都是单例的,如果我想每次都拿到一个新的Bean,如何配置呢?
深入理解Spring —— Bean的更新

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值