Spring中,给静态变量初始化的问题

方案一:使用@PostConstruct注解

首先,声明一个静态变量staticTarget,静态变量staticTarget的类型要和非静态变量target的类型一致。
然后,在带有@PostConstruct注解的方法中,将target的值赋给staticTarget。
最后,在静态方法中通过调用静态变量staticTarget来实现对非静态变量target的调用。

说明:
	1)在指定方法上加上@PostConstruct 注解来指定该方法是在bean初始化之后调用
	2)在指定方法上加上@PreDestroy 注解来指定该方法是在bean销毁之前调用

方案二:使用@PostConstruct注解

首先,声明一个静态变量factory,这个静态变量factory的类型为该类自身。
然后,在带有@PostConstruct注解的方法中,将this赋给这个静态变量factory,此时,factory指向了一个该类的实例(在容器启动的时候创建),故factory可以访问到该实例中的字段。
最后,在静态方法中,通过调用静态变量factory来访问该类中的非静态变量。

例子:
	@Component
	public class FailureTool {
		
	/*	// 方案一:
		@Autowired
		private MailUtil target1;
		
		@Autowired
		private ThreadPoolTaskExecutor target2;

		private static MailUtil staticTarget1;
		private static ThreadPoolTaskExecutor staticTarget2;
		
		@PostConstruct 
		public void init(){
			staticTarget1 = target1;
			staticTarget2 = target2;
		}*/
		
		
		// 方案二:
		@Autowired
		private MailUtil mailUtil;
		
		@Autowired
		private ThreadPoolTaskExecutor taskExecutor;
		
		private static FailureTool factory; 
		
		@PostConstruct 
		public void init(){
			factory = this;
		}
		
		public static void sendMail(AccountQuotaMonitor accountQuotaMonitor) {

		/*	// 方案一
			SendMailTask sendMailTask = new SendMailTask(staticTarget1, accountQuotaMonitor);
			FutureTask<Integer> futureTask = new FutureTask<Integer>(sendMailTask);
			staticTarget2.submit(futureTask);	*/
			
			// 方案二
			SendMailTask sendMailTask = new SendMailTask(factory.mailUtil, accountQuotaMonitor);
			FutureTask<Integer> futureTask = new FutureTask<Integer>(sendMailTask);
			factory.taskExecutor.submit(futureTask);
			
		}
	}

方案三:通过实现ApplicationContextAware接口来获取到Spring的ApplicationContext,进而可以获取到容器中的任何对象。

说明:
	1)实现ApplicationContextAware接口的类,Spring在实例化该类时会自动调用setApplicationContext方法,
	2)在setApplicationContext方法中,将类型为ApplicationContext的入参的值赋值给该类的一个静态变量,
	3)然后就可以通过调用静态的getApplicationContext方法来获取到该类的静态变量,也即获取到了ApplicationContext。
	
例子:
	
	@Component // 注:必须添加@Component注解,因为该类的实例化操作必须由Spring来完成。
	public class ApplicationContextUtil implements ApplicationContextAware {

		private static ApplicationContext context;

		@Override
		public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
			// TODO Auto-generated method stub
			ApplicationContextUtil.context = applicationContext;
		}

		public static ApplicationContext getApplicationContext() {
			return context;
		}
	}
	
	
	public class FailureTool {
		
		private static MailUtil mailUtil;
		private static ThreadPoolTaskExecutor taskExecutor;

		static {
			mailUtil = ApplicationContextUtil.getApplicationContext().getBean(MailUtil.class);
			taskExecutor = ApplicationContextUtil.getApplicationContext().getBean(ThreadPoolTaskExecutor.class);
		}
		
		public static void sendMail(AccountQuotaMonitor accountQuotaMonitor) {
			SendMailTask sendMailTask = new SendMailTask(mailUtil, accountQuotaMonitor);
			FutureTask<Integer> futureTask = new FutureTask<Integer>(sendMailTask);
			taskExecutor.submit(futureTask);
		}
	}

猜你喜欢

转载自my.oschina.net/u/1399755/blog/1647437