spring在web容器启动时执行初始化方法

需求:在tomcat启动时开启一个定时任务。

想法:容器启动时执行方法,最容易想到的就是servlet中可以配置load-on-startup,设置一个正整数也就可以随容器一起启动。

问题:上面的方法很好,但是由于定时任务需要去操作数据库,而项目采用了spring的依赖注入来管理对象,而servlet并不受Spring的管理。若此时在servlet中注入Spring管理的对象,则会报错:javax.naming.NameNotFoundException: Name com.test.InitServlet is not bound in this Context。

所以想要再servlet中操作数据库,只能手动去创建一个service,这显然违背了我们使用Spring的初衷,让项目看起来不伦不类的。那么如何才能在启动WEB容器的时候执行一段初始化代码,并且可以让其被Spring管理呢?

解决方案:Spring提供了当一个Bean初始化后执行方法的扩展点:InitializingBean。这里的初始化指的就是当该Bean的属性被注入完成后(注意:这里并不是所有属性都需要被设置),所以InitializingBean接口提供的方法名称也很形象:afterPropertiesSet()。

使用的时,将该Bean注入到Spring容器,之后我们便可以获得Spring容器中的对象了,也就是说,可以得到service方法来执行我们的定时任务了。

具体代码如下:

@Component
public class InitServlet implements InitializingBean {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Resource
	private DispatchesService dispatchesService;

	@Override
	public void afterPropertiesSet() throws Exception {
	<span style="white-space:pre">	</span>dispatchesService.spyDDetails();
	}

}

另外还有两种方法也可以实现如上的功能。

1、若采用XML来配置Bean的话,可以指定属性init-method

2、通过注解@PostConstruct来修改初始化方法

值得注意的是,三者可以同时存在,触发的顺序是先触发@PostConstruct修饰的方法,再触发afterPropertiesSet(),最后触发init-method

其中@PostConstruct是通过注册一个BeanPostProcessor,在Bean的初始化方法之前调用,而afterPropertiesSet()和init-method都在初始化方法中调用

关于@PostConstruct详细的介绍可以看这里:http://blog.csdn.net/yaerfeng/article/details/8447530

下面是Spring中调用Bean的初始化代码的源代码:

	protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						public Object run() throws Exception {
							((InitializingBean) bean).afterPropertiesSet();<span style="white-space:pre">	</span><span style="font-family: Arial, Helvetica, sans-serif;">// 这里触发afterPropertiesSet</span><span style="white-space:pre">
</span>
							return null;
						}
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}				
			else {
				((InitializingBean) bean).afterPropertiesSet();<span style="white-space:pre">	</span>// 这里触发afterPropertiesSet
			}
		}

		if (mbd != null) {
			String initMethodName = mbd.getInitMethodName();// 这里是触发init-method
			if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}


补充:

还有一种方法,是当Spring将所有的Bean都初始化完成后,会留给我们一个入口,我们可以实现如下接口

@Component
public class InstantiationTracingBeanPostProcessor implements
		ApplicationListener<ContextRefreshedEvent> {

	@Override
	public void onApplicationEvent(ContextRefreshedEvent arg0) {
		System.out.println("-----所有Bean载入完成---");
	}
}


Spring容器启动时初始化Druid连接池的过程通常涉及到以下几个步骤: 1. **配置文件**:首先,在Spring Boot应用的`application.properties`或`application.yml`等配置文件中,你需要设置Druid的相关属性,如数据源名称、驱动、URL、用户名、密码以及最大连接数等。 ```properties druid.datasource.url=jdbc:mysql://localhost:3306/mydb druid.datasource.username=root druid.datasource.password=yourpassword druid.initial-size=5 max-active=20 ``` 2. **依赖注入**:在Spring的XML配置或者注解配置中,通过`@Bean`或`<bean>`标签,创建一个`DruidDataSource` bean,并将其关联到Spring管理的数据源名上。例如: ```xml <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 配置信息... --> </bean> ``` 或者使用Java配置: ```java @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); // 配置信息... return dataSource; } ``` 3. **初始化方法**:`init-method`属性指定了DruidDataSource的初始化方法`init()`,它会在Spring容器启动时自动调用,完成数据库连接池的初始化工作。 4. **监控和日志**:Druid还提供了丰富的监控功能,可以查看其连接池的状态,包括连接数、空闲数等,这通常需要额外引入Druid的Web监控模块并配置访问路径。 当你启动Spring应用时,Spring容器会按照配置顺序加载和初始化各个组件,包括Druid连接池。如果一切配置正确,那么在应用程序运行起来后,Druid的连接池就已经准备就绪了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值