Java動態(tài)腳本Groovy獲取Bean技巧
在Groovy中不能使用@Autowired(autowired是在spring啟動后注入的,此時還未加載groovy代碼,故無法注入)
一、使用BeanFactoryPostProcessor注入Bean:
它與 BeanPostProcessor接口類似,可以對bean的定義(配置元數(shù)據(jù))進(jìn)行處理;也就是spring ioc運(yùn)行BeanFactoryPostProcessor在容器實(shí)例化任何其他的bean之前讀取配置元數(shù)據(jù),并有可能修改它;如果業(yè)務(wù)需要,可以配置多個BeanFactoryPostProcessor的實(shí)現(xiàn)類,通過"order"控制執(zhí)行次序(要實(shí)現(xiàn)Ordered接口)。
第一步:創(chuàng)建實(shí)現(xiàn)SpringUtils 接口工具(組件)來獲取spring bean
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements BeanFactoryPostProcessor {
/** Spring應(yīng)用上下文環(huán)境 \*/
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
public static <T> T getBean(Class<T> clz) throws BeansException
{
T result = (T) beanFactory.getBean(clz);
return result;
}
}
第二步:創(chuàng)建Groovy腳本裝載類,動態(tài)解析腳本為Class
package com.example.groovy.testgroovy.task;
import groovy.lang.GroovyClassLoader;
public class GroovyUtils {
private final static ClassLoader classLoader = GroovyUtils.class.getClassLoader();//獲取當(dāng)前類裝載器
//ClassLoader:就是類的裝載器,它使JVM可以動態(tài)的載入Java類,JVM并不需要知道從什么地方(本地文件、網(wǎng)絡(luò)等)載入Java類,這些都由ClassLoader完成。
public final static GroovyClassLoader groovyClassLoader = new GroovyClassLoader(classLoader);
//GroovyClassLoader:負(fù)責(zé)在運(yùn)行時編譯groovy源代碼為Class的工作,從而使Groovy實(shí)現(xiàn)了將groovy源代碼動態(tài)加載為Class的功能。
/**
* .
* 獲取實(shí)例化對象
* @param script groovy腳本內(nèi)容
* @param <T>
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static <T> T instanceTaskGroovyScript(String script) throws IllegalAccessException, InstantiationException {
Class taskClz = groovyClassLoader.parseClass(script);
T instance = (T) taskClz.newInstance();
return instance;
}
}
第三步:讀取腳本內(nèi)容,執(zhí)行腳本
@Slf4j
@Component
public class CallAnalysisGroovyTask {
/**
* .
* 讀取腳本內(nèi)容
*
* @return
*/
public String getGroovy() {
String context = "";
try {
String path = "E:\\IDEAFile\\testgroovy\\src\\main\\resources\\groovy\\LoadBean.groovy";
context = FileUtils.readFileToString(new File(path));//將腳本內(nèi)容轉(zhuǎn)為字符串
} catch (IOException e) {
log.error("file is not found[{}]", e);
}
return context;
}
/**
* .
* 執(zhí)行g(shù)roovy腳本
*
* @param script
*/
public void execGroovy(String script) {
try {
Runnable runnable = GroovyUtils.instanceTaskGroovyScript(script);//獲取實(shí)例對象
runnable.run();//調(diào)用腳本方法
} catch (Exception t) {
log.error("execGroovy file {} error", script);
}
}
}
第四步:在resources目錄下創(chuàng)建.groovy文件
@Slf4j
class LoadBean implements Runnable {
/**
* .
* Groovy獲取Bean
*/
@Override
void run() {
log.info("Groovy開始執(zhí)行,當(dāng)前類{}", this.getClass())
ScriptService service = SpringUtils.getBean(ScriptService.class)
log.info("ApplicationContext獲取對象[{}]", service.class)
List<Script> item = service.findAll()//執(zhí)行bean中數(shù)據(jù)查詢方法
for (Script s : item) {
log.info("創(chuàng)建人:[{}],規(guī)則id:[{}],名稱:[{}]", s.getCreatePerson(), s.getRuleId(), s.getScriptName())
}
log.info("Groovy結(jié)束執(zhí)行,當(dāng)前類{}", this.getClass())
}
}
第五步:實(shí)例化腳本,執(zhí)行方法?
@GetMapping("/loadBean")
public void loadBean(){
String script = CallAnalysisGroovyTask.getGroovy(); //獲取腳本
CallAnalysisGroovyTask.execGroovy(script);//實(shí)例化腳本,執(zhí)行方法
log.info("數(shù)據(jù)查詢成功...");
}
腳本運(yùn)行結(jié)果:

二、使用ApplicationContext注入Bean
它是spring繼BeanFactory之外的另一個核心接口或容器,允許容器通過應(yīng)用程序上下文環(huán)境創(chuàng)建、獲取、管理bean。為應(yīng)用程序提供配置的中央接口。在應(yīng)用程序運(yùn)行時這是只讀的,但如果實(shí)現(xiàn)支持這一點(diǎn),則可以重新加載。
第一步:修改項(xiàng)目啟動類,獲得ApplicationContext
@SpringBootApplication
public class TestgroovyApplication {
//獲取應(yīng)用程序上下文環(huán)境
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(TestgroovyApplication.class, args);
}
第二步:修改resources目錄下創(chuàng)建的.groovy文件
/**
* .
* Groovy獲取Bean
*/
@Override
void run() {
log.info("Groovy開始執(zhí)行,當(dāng)前類{}", this.getClass())
ScriptService service = TestgroovyApplication.applicationContext.getBean(ScriptService.class)
log.info("ApplicationContext獲取對象[{}]", service.class)
List<Script> item = service.findAll()//執(zhí)行bean中數(shù)據(jù)查詢方法
for (Script s : item) {
log.info("創(chuàng)建人:[{}],規(guī)則id:[{}],名稱:[{}]", s.getCreatePerson(), s.getRuleId(), s.getScriptName())
}
log.info("Groovy結(jié)束執(zhí)行,當(dāng)前類{}", this.getClass())
}
腳本運(yùn)行結(jié)果:

到此這篇關(guān)于Java動態(tài)腳本Groovy獲取Bean技巧的文章就介紹到這了,更多相關(guān)Java動態(tài)腳本Groovy獲取Bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
本地編譯打包項(xiàng)目部署到服務(wù)器并且啟動方式
這篇文章主要介紹了本地編譯打包項(xiàng)目部署到服務(wù)器并且啟動方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
使用spring攔截器實(shí)現(xiàn)日志管理實(shí)例
本篇文章主要介紹了使用spring攔截器實(shí)現(xiàn)日志管理實(shí)例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03
ajax實(shí)時監(jiān)測與springboot的實(shí)例分析
本文將介紹如何使用 AJAX 技術(shù)結(jié)合 Spring Boot 構(gòu)建一個實(shí)時反饋用戶輸入的應(yīng)用,我們將創(chuàng)建一個簡單的輸入框,當(dāng)用戶在輸入框中鍵入文本時,應(yīng)用將異步地向后端發(fā)送請求,感興趣的朋友跟隨小編一起看看吧2024-07-07
SpringBoot EasyPoi動態(tài)導(dǎo)入導(dǎo)出的兩種方式實(shí)現(xiàn)方法詳解
項(xiàng)目里使用的是EasyPoi來處理導(dǎo)入導(dǎo)出功能的。近日因業(yè)務(wù)需求調(diào)整,一些導(dǎo)出功能的導(dǎo)出列需要根據(jù)不同的條件動態(tài)導(dǎo)出2022-09-09
Java如何實(shí)現(xiàn)將類文件打包為jar包
這篇文章主要介紹了Java如何實(shí)現(xiàn)將類文件打包為jar包,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
Java服務(wù)假死后續(xù)之內(nèi)存溢出的原因分析
這篇文章主要介紹了Java服務(wù)假死后續(xù)之內(nèi)存溢出,本文給大家分享原因排查和故障解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07

