ApplicationContextAware接口的拓展和使用
ApplicationContextAware接口只有一個方法:
public interface ApplicationContextAware extends Aware {void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }此接口的介紹:
不用類似new ClassPathXmlApplicationContext()的方式,從已有的spring上下文取得已實例化的bean。通過ApplicationContextAware接口進行實現。
當一個類實現了這個接口(ApplicationContextAware)之后,這個類就可以方便獲得ApplicationContext中的所有bean。換句話說,就是這個類可以直接獲取spring配置文件中,所有有引用到的bean對象。
官方介紹的翻譯:
接口由希望被其運行的ApplicationContext通知的任何對象實現。
實現這個接口是有意義的,例如,當一個對象需要訪問一組協作bean時。請注意,通過bean引用進行配置比僅僅為了bean查找目的實現此接口更可取。
如果一個對象需要訪問文件資源,例如,想要調用getResource,想要發布一個應用事件,或者需要訪問MessageSource,這個接口也可以實現。然而,最好在這樣一個特定的場景中實現更具體的ResourceLoaderAware、ApplicationEventPublisherAware或MessageSourceAware接口。
參數applicationContext—要被該對象使用的applicationContext對象
ApplicationContextAware接口的作用
實現**ApplicationContextAware**接口。重寫或繼承里面的方法。
主要可以實現的功能:
需要注意的是,需要將這個類放入Spring容器中管理。即使用**@Component**注解。
需要注意的是:name不是Bean對象的全限定名,而是Spring容器中的Bean名。
實現setApplicationContext此方法的類:
使用實例
@Slf4j public class SpringContextHolder implements ApplicationContextAware, DisposableBean { //DisposableBean :由希望在銷毀時釋放資源的bean實現的接口。 // BeanFactory將在對作用域bean的單獨銷毀時調用destroy方法。 // applicationcontext應該在關閉時釋放它的所有單例對象,這是由應用生命周期驅動的。 //出于同樣的目的,spring管理的bean也可以實現Java的AutoCloseable接口。 // 實現接口的另一種方法是指定自定義destroy方法,例如在XML bean定義中。private static ApplicationContext applicationContext = null;/*** 從靜態變量applicationContext中取得Bean, 自動轉型為所賦值對象的類型.*/@SuppressWarnings("unchecked")public static <T> T getBean(String name) {assertContextInjected();return (T) applicationContext.getBean(name);}/*** 從靜態變量applicationContext中取得Bean, 自動轉型為所賦值對象的類型.*/public static <T> T getBean(Class<T> requiredType) {assertContextInjected();return applicationContext.getBean(requiredType);}/*** 檢查ApplicationContext不為空.*/private static void assertContextInjected() {if (applicationContext == null) {throw new IllegalStateException("applicaitonContext屬性未注入, 請在applicationContext" +".xml中定義SpringContextHolder或在SpringBoot啟動類中注冊SpringContextHolder.");}}/*** 清除SpringContextHolder中的ApplicationContext為Null.*/private static void clearHolder() {log.debug("清除SpringContextHolder中的ApplicationContext:"+ applicationContext);applicationContext = null;}@Overridepublic void destroy() {SpringContextHolder.clearHolder();}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if (SpringContextHolder.applicationContext != null) {log.warn("SpringContextHolder中的ApplicationContext被覆蓋, 原有ApplicationContext為:" + SpringContextHolder.applicationContext);}SpringContextHolder.applicationContext = applicationContext;} }使用這個上面類在線程對象中得到目標對象的方法,利用反射進行調用:
public class QuartzRunnable implements Callable { //在Execution類中使用QuartRunnable QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), // quartzJob.getParams()); // Future<?> future = EXECUTOR.submit(task);private Object target;private Method method;private String params;QuartzRunnable(String beanName, String methodName, String params)throws NoSuchMethodException, SecurityException {this.target = SpringContextHolder.getBean(beanName);this.params = params;if (StringUtils.isNotBlank(params)) {this.method = target.getClass().getDeclaredMethod(methodName, String.class);} else {this.method = target.getClass().getDeclaredMethod(methodName);}}@Overridepublic Object call() throws Exception {ReflectionUtils.makeAccessible(method);if (StringUtils.isNotBlank(params)) {method.invoke(target, params);} else {method.invoke(target);}return null;} }method.invoke(target, params):
對目標object執行方法method,參數為params
調用反射的方法:
@Async public class ExecutionJob extends QuartzJobBean { //在QuartManage類中 JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class). // withIdentity(JOB_NAME + quartzJob.getId()).build();//執行定時任務 // scheduler.scheduleJob(jobDetail, cronTrigger);/** 該處僅供參考 */private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();@Override@SuppressWarnings("unchecked")protected void executeInternal(JobExecutionContext context) {//(1)當Scheduler調用一個Job,就會將JobExecutionContext傳遞給job的execute方法// quartz無法調用job的有參構造函數,所以創建job的實例的時候是運用反射機制,通過newInstance創建實例,// 并且通過JobDetail描述的name與group屬性然后給Job設置一些屬性。////(2)Job能通過JobExecutionContext對象訪問到Quartz運行時候的環境以及Job本身的明細數據。QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);// 獲取spring beanQuartzLogService quartzLogService = SpringContextHolder.getBean(QuartzLogService.class);QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class);QuartzLog log = new QuartzLog();long startTime = System.currentTimeMillis();try {// 執行任務 QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),quartzJob.getParams());//這句話中執行了該線程Future<?> future = EXECUTOR.submit(task);future.get();long times = System.currentTimeMillis() - startTime; } catch (Exception e) {logger.error("任務執行失敗,任務名稱:{}" + quartzJob.getJobName(), e);long times = System.currentTimeMillis() - startTime;log.setTime(times);log.setExceptionDetail(ThrowableUtil.getStackTrace(e));quartzJob.setIsPause(false);//更新狀態quartzJobService.updateIsPause(quartzJob);} finally {quartzLogService.save(log);}} }總結
以上是生活随笔為你收集整理的ApplicationContextAware接口的拓展和使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shiro的登录 subject.log
- 下一篇: 【多线程编程学习】java多线程基于数据