spring + groovy 很强大

4 篇文章 0 订阅

groovy是一门基于JVM的动态语言,跟spring结合更显强大,废话不多说,直接上例子

1、定义java接口 Foo.java

package groovy;

public interface Foo {
	void execute();
}

2、定义Groovy实现类 FooImpl.groovy

package groovy

import groovy.Foo

class FooImpl implements Foo {
	
	void execute() {
		println("hello!");
	}
	
}

3、定义spring配置文件 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang"
	xmlns:gorm="http://grails.org/schema/gorm"
	xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://grails.org/schema/gorm http://grails.org/schema/gorm/gorm.xsd">

	<lang:groovy refresh-check-delay="500" script-source="groovy/FooImpl.groovy"></lang:groovy>

</beans>

4、测试类 GroovyTest.java

package groovy;

import java.util.Scanner;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class GroovyTest {
	public static void main(String[] args) {
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		Foo foo = context.getBean(Foo.class);
		Scanner in = new Scanner(System.in);
		while (true) {
			System.out.println("输入任意键");
			in.next();
			foo.execute();
		}
		
	}
}

ok,运行测试


修改FooImpl.groovy

package groovy

import groovy.Foo

class FooImpl implements Foo {
	
	void execute() {
		println("hello world!");
	}
	
}

到控制台再次输入



测试成功,程序不用重启,即可看到修改后的结果,再也不用其他热加载的插件了。

但是这样感觉不太爽,要是有很多接口实现类的话,不是要写一大堆配置文件?

虽然可以copy,也可以自动生成,但是我觉得还是不够完美,想个办法解决掉,办法就是动态加载bean,编写一个初始化bean,下次直接用即可。


该bean需要实现ApplicationContextAware接口,该接口可以拿到ApplicationContext,也就是spring容器,有了这个,我们就可以自己加一些bean到这个容器当中了。

为了实现这个效果,我可是花了不少功夫,由于网上又没有这个资料,只能自己硬着头皮,看源代码,终于皇天不负有心人 被我实现了,拿来共享一下

1、首先需要顶一个一个类实现ApplicationContextAware接口  GroovyFactory.java

package groovy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class GroovyFactory implements ApplicationContextAware {

	@Override
	public void setApplicationContext(ApplicationContext context)
			throws BeansException {
		// 只有这个对象才能注册bean到spring容器
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
		
		// 因为spring会自动将xml解析成BeanDefinition对象然后进行实例化,这里我们没有用xml,所以自己定义BeanDefinition
		// 这些信息跟spring配置文件的方式差不多,只不过有些东西lang:groovy标签帮我们完成了
		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setBeanClassName("org.springframework.scripting.groovy.GroovyScriptFactory");
		final String refreshCheckDelay = "org.springframework.scripting.support.ScriptFactoryPostProcessor.refreshCheckDelay";
		final String language = "org.springframework.scripting.support.ScriptFactoryPostProcessor.language";
		// 刷新时间
		bd.setAttribute(refreshCheckDelay, 500);
		// 语言脚本
		bd.setAttribute(language, "groovy");
		// 文件目录
		bd.getConstructorArgumentValues().addIndexedArgumentValue(0, "groovy/FooImpl.groovy");
		// 注册到spring容器
		beanFactory.registerBeanDefinition("Foo", bd);
	}
	
}

2、然后将这个bean配置到applicationContext.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang"
	xmlns:gorm="http://grails.org/schema/gorm"
	xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://grails.org/schema/gorm http://grails.org/schema/gorm/gorm.xsd">

	<!-- 
	<lang:groovy refresh-check-delay="500" script-source="groovy/FooImpl.groovy"></lang:groovy>
	 -->
	 
	<bean class="groovy.GroovyFactory"></bean> 
	
	<bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor"/>

</beans>

3、这个多出了一个bean配置,事实上,这个bean在我们采用第一种方法配置的时候,spring后自动创建这个bean,然后我们没有采用这个方式,所以只能手动配置

4、运行程序,应该更刚才的结果是一样的

写到这里,可能会有人说我是多此一举了,不急,只要把GroovyFactory稍微修改一下,让其接受一个参数,其作用就明显,其参数是一个目录名,得到此目录名后,我们的bean就可以去扫描这个目录下的所有groovy文件,然后将其动态添加到spring容器中,这样无论我们添加了多少groovy类,都不需要去修改配置了,继续...

修改GroovyFactory.java

package groovy;

import java.io.File;
import java.io.FileFilter;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class GroovyFactory implements ApplicationContextAware {

	private String directory;
	
	public String getDirectory() {
		return directory;
	}

	public void setDirectory(String directory) {
		this.directory = directory;
	}

	@Override
	public void setApplicationContext(ApplicationContext context)
			throws BeansException {
		// 只有这个对象才能注册bean到spring容器
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
		
		// 因为spring会自动将xml解析成BeanDefinition对象然后进行实例化,这里我们没有用xml,所以自己定义BeanDefinition
		// 这些信息跟spring配置文件的方式差不多,只不过有些东西lang:groovy标签帮我们完成了
		final String refreshCheckDelay = "org.springframework.scripting.support.ScriptFactoryPostProcessor.refreshCheckDelay";
		final String language = "org.springframework.scripting.support.ScriptFactoryPostProcessor.language";
		
		String realDirectory = Thread.currentThread().getContextClassLoader().getResource(directory).getFile();
		File root = new File(Thread.currentThread().getContextClassLoader().getResource(".").getFile());
		
		File[] files = new File(realDirectory).listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				return pathname.getName().endsWith(".groovy") ? true : false;
			}
		});
		for (File file : files) {
			GenericBeanDefinition bd = new GenericBeanDefinition();
			bd.setBeanClassName("org.springframework.scripting.groovy.GroovyScriptFactory");
			// 刷新时间
			bd.setAttribute(refreshCheckDelay, 500);
			// 语言脚本
			bd.setAttribute(language, "groovy");
			// 文件目录
			bd.getConstructorArgumentValues().addIndexedArgumentValue(0, file.getPath().replace(root.getPath(), ""));
			// 注册到spring容器
			beanFactory.registerBeanDefinition(file.getName().replace(".groovy", ""), bd);
		}
		
	}
	
}

接着修改applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang"
	xmlns:gorm="http://grails.org/schema/gorm"
	xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://grails.org/schema/gorm http://grails.org/schema/gorm/gorm.xsd">

	<!-- 
	<lang:groovy refresh-check-delay="500" script-source="groovy/FooImpl.groovy"></lang:groovy>
	 -->
	 
	<bean class="groovy.GroovyFactory">
		<property name="directory" value="groovy"/>
	</bean> 
	
	<bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor"/>

</beans>
运行程序,结果跟上面一样,不一样的就是GroovyFactory从加载单个类,变成扫描目录,更实用了。

项目结构如下:



项目文件就不贴了,有需要的留言吧,累死了



  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Groovy是一种基于JVM的动态语言,它可以与Java代码互操作,并且在编写代码时具有更高的灵活性和可读性。Spring是一个流行的Java框架,用于构建企业级Web应用程序和服务。 Spring支持Groovy脚本的托管,这意味着您可以使用Groovy编写Spring应用程序,并将其部署到Spring容器中。这种方式可以提供更加灵活的编程方式,同时保留Spring强大功能。 要使用Groovy编写Spring应用程序,您需要使用Spring Boot框架的Groovy支持。Spring Boot为Groovy开发提供了一个特殊的starter包,其中包含了必要的依赖项和配置文件。 以下是一些使用Groovy编写Spring Boot应用程序的示例: 1. 定义一个基本的Spring Boot应用程序类,使用Groovy语言编写 ``` import org.springframework.boot.* import org.springframework.boot.autoconfigure.* import org.springframework.stereotype.* import org.springframework.web.bind.annotation.* @RestController @EnableAutoConfiguration class Example { @RequestMapping("/") String home() { "Hello World!" } static void main(String[] args) { SpringApplication.run(Example.class, args) } } ``` 2. 在应用程序类中使用Groovy语言定义Bean ``` import org.springframework.context.annotation.* @Configuration class MyConfiguration { @Bean MyBean myBean() { new MyBean() } } class MyBean { String message = "Hello from Groovy Bean!" } ``` 3. 在应用程序配置文件中使用Groovy语言定义配置项 ``` spring: datasource: url: jdbc:mysql://localhost/mydb username: myuser password: mypassword ``` 这些示例只是GroovySpring合作的一些示例,您可以根据需要编写Groovy代码,并使用Spring框架将其托管。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值