1 Star 1 Fork 23

boobor / jBeanBox

forked from drinkjava2 / jBeanBox 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
BSD-3-Clause

jBeanBox是一个微形(只有单个Java文件约1000行源码)但功能较齐全的IOC/AOP工具,利用了Java的初始化块实现的Java配 置代替XML,比目前Spring或Guice的Java配置更简单更实用。jBeanBox遵循BSD-3开源协议,目前的版本是jBeanBox2.2。 其他一些IOC / AOP框架问题: 1)Spring,HiveMind的和其他IOC/AOP工具使用XML作为配置文件:XML不支持类名称拼写检查和IDE重构,很难在运行时更改 配置。(从Spring3.0开始使用基于一种Java配置来取代XML,但Java配置与与注解混用,复杂且不支持配置的继承重用,如果 使用方法名作为Bean的ID则不支持类名的IDE重构。), 我的看法是,作为一个IOC/AOP工具来说它太大太复杂了。 2)Guice和其他依赖于注解的IOC/AOP项目:注解是一种拉式注入,入侵性强,不支持第三方库,IOC/AOP工具不应该完全依赖于更改Java源码。

jBeanBox的特点: 1)简单,仅一个Java文件做所有的IOC/AOP工作,没有XML,只有1个注释。易于学习、使用和修改源代码。 2)使用Java来代替XML,其实现比Spring或Guice的Java配置更简单更自然,支持配置的继承重用。 3)jBeanBox是一个麻雀虽小、功能俱全的IOC/AOP工具,旨在小项目中取代Spring IoC/AOP内核,它具有的主要功能有: *以Box封装为基础的Java配置类(称为“BeanBox”)来代替XML,配置可以在运行期创建和修改。 *Bean实例延迟初始化(如Guice类似) *单例/多例支持,默认情况下所有实例为单例(与Spring类似) *单例缓存 *内置AOP和AspectJ支持 *多种注射机制: 推式注入:值注入,实例注入,构造方法注入,静态工厂注入,实例工厂注入 (与Spring传统XML注入类似) 拉式注入:利用@InjectBox注解 (与Guice和Spring的注解注入类似) *多上下文的支持(除了默认的全局范围上下文外,它支持多个上下文,类似于Spring中创建多个ApplicationContext实例) *支持Bean生命周期管理(postConstruction和preDestory方法支持)

如何使用jBeanBox? 从jBeanBox项目网站下载jbeanbox-x.x.jar或jbeanbox-x.x-src.jar或者是BeanBox.java源文件,并把以下4个包放入lib目录: http://central.maven.org/maven2/aopalliance/aopalliance/1.0/aopalliance-1.0.jar http://central.maven.org/maven2/asm/asm/3.3.1/asm-3.3.1.jar http://central.maven.org/maven2/org/aspectj/aspectjrt/1.8.9/aspectjrt-1.8.9.jar http://central.maven.org/maven2/cglib/cglib/2.2.2/cglib-2.2.2.jar (项目尚待按Meven目录格式整理,但目前可从项目页下载打包好的的Demo_jBeanBoxx.x.war查看示例)

基本用法: 示例1 - 基本用法(各种注入):

public class OrderBox extends BeanBox {//这是用于取代XML的JAVA配置类
	{       //setClassOrValue(Order.class);   //目标类或数值的设定,如使用getBean()调用可省略
		setProperty("orderNO", "PO#20160214");//值注入
		setProperty("company", CompanyBox.class);// Inject a bean                                  setProperty("orderItem1", new BeanBox(OrderItem.class,"Dog1",77.99));//构造器注入
		setStaticFactory("orderItem2", OrderItemFactory.class, "createOrderItem", "Dog2", 88.99);//静态工厂注入
		BeanBox factory = new BeanBox(OrderItemFactory.class, new CompanyBox(), false);
		setBeanFactory("orderItem3", factory, "createOrderItem2", new CompanyBox(), "Dog3", 99.99);//实例工厂注入
	}

	public static class CompanyBox1 extends BeanBox {
		{
			setClassOrValue(Company.class);
			setProperty("name", "Company1");
		}
	}

	public static class CompanyBox extends CompanyBox1 {//配置的继承
		{
			setProperty("name", "Company2");//属性覆盖
		}
	}
}

public class Tester {
	public static void main(String[] args) {
		Order order = BeanBox.getBean(Order.class);
		order.printALlItems();
		System.out.println("Order bean is a SingleTon? " + (order == new OrderBox().getBean()));//true
	}
}

以上"Company", "Order", "OrderItem", "OrderItemFactory"为普通Java类,源码见"Demo_jBeanBox2.1.war"示例。

示例2: AOP & Aspectj 演示

public class Tester {
	private Iitem item;

	public void setItem(Iitem item) {
		this.item = item;
	}

	public void doPrintItem() {
		item.doPrint();
	}

	public static void main(String[] args) {
		BeanBox advice = new BeanBox(AOPLogAdvice.class).setProperty("name", "AOP Logger");
		BeanBox.defaultContext.setAOPAround("examples.example2_aop.\\w*", "doPrint\\w*", advice, "doAround");
		
		BeanBox advice2 = new BeanBox(AspectjLogAdvice.class).setProperty("name", "AspectJ Logger");
		BeanBox.defaultContext.setAspectjAfterReturning("examples.example2_aop.\\w*", "doPrint\\w*", advice2, "doAfterReturning");

		Tester t = new BeanBox(Tester.class) {
			{ this.setProperty("item", ItemImpl.class);
			}
		}.getBean();
		t.doPrintItem();
	}
}

BeanBox.defaultContext是个单例类全局变量,对于无需创建多个上下文实例的小型项目可以直接使用这个全局实例变量以简化编码。

示例3: @injectBox注解和上下文演示 此项目有且仅有一个注解@injectBox,注入1到7为注解注入,属于拉式注入,注入8和9为传统无侵入的推式注入。 可以看出,注解的引入可极大简化源码,提高开发效率,但代价是难以理解和维护,且不支持无源码的第三方库。

public class Tester {
	@InjectBox(A.StrBox.class)
	String s1;// Use StrBox.class

	@InjectBox(A.class)
	String s2;// Use A.StringBox.class (or A.StringBox2.class, 2 to 8 depends context setting)

	@InjectBox(B.class)
	String s3;// Use B$S3Box.class

	@InjectBox
	C c4;// Use CBox.class

	@InjectBox
	String s5;// Use TesterBox$StringBox.class

	@InjectBox(required = false)
	D d6;// Use Config$DBox.class (or Config2$DBox2)

	@InjectBox(required = false)
	E e7;// Use Config$E7Box.class (or Config2$E7Box2)

	private String s8; // injected by field, not suitable for Proxy bean

	private String s9; // injected by setter method

	public void setS9(String s9) {
		this.s9 = s9;
	}

	public void print() {
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
		System.out.println((c4 == null) ? null : c4.value);
		System.out.println(s5);
		System.out.println((d6 == null) ? null : d6.value);
		System.out.println((e7 == null) ? null : e7.value);
		System.out.println(s8);
		System.out.println(s9);
		System.out.println(this);
	}

	public static void main(String[] args) {
		Tester t = BeanBox.getBean(Tester.class);
		t.print();

		BeanBoxContext ctx = new BeanBoxContext(Config2.class).setBoxIdentity("Box2");
		Tester t3 = ctx.getBean(Tester.class);
		t3.print();
	}
}

示例4: Bean的生命周期管理(PostConstructor和PreDestory方法回调)

public class Tester {
	private String name;

	public void init() {
		name = "Sam";
	}

	public void destory() {
		System.out.println("Bye " + name);
	}

	public static class TesterBox extends BeanBox {
		{
			setPostConstructor("init");
			setPreDestory("destory");
		}
	}

	public static void main(String[] args) {
		BeanBox.getBean(Tester.class);
		BeanBox.defaultContext.close();// print Bye Sam
	}
}

示例5: 利用jBeanBox取代Spring内核实现无XML的声明式事务 声明式事务是AOP的典型运用场合,基本原理是利用线程局部变量来管理连接,AOP的特点就是服务和内核是插拔式设计,内核和 服务可以单独使用。Spring中提供的一些业务支持理论上都可以抽取出来在其它IOC/AOP工具上使用,如果抽取不出来,说明它 绑死在Spring内核上了,这与它的设计理念是不符的。本着不重新发明轮子的原则,此示例将Spring中的声明式事务服务抽取出 来,与jBeanBox整合,也就是说这一次的整合只利用了Spring的事务服务,而不使用它的IOC/AOP内核 ,很诡异的组合,但目 的很明确:取消XML配置。以下是jBeanBox整合了c3p0数据池+JDBCTemplate+Spring声明式事务的一个例子,实测通过:

public class TesterBox extends BeanBox {//用于取代XML的JAVA配置类
	static {//在默认全局单例上下文上设置AOP事务切面
		BeanBox.defaultContext.setAOPAround("examples.example5_transaction.Test\\w*", "insert\\w*", new TxInterceptorBox(), "invoke");
	}

	static class DSPoolBeanBox extends BeanBox {//C3P0数据池配置,为单例,下同
		{
			setClassOrValue(ComboPooledDataSource.class);
			setProperty("jdbcUrl", "jdbc:mysql://127.0.0.1:3306/test?user=root&password=yourPWD&useUnicode=true&characterEncoding=UTF-8");
			setProperty("driverClass", "com.mysql.jdbc.Driver");// your jdbc driver name
			setProperty("maxPoolSize", 10);
		}
	}

	static class TxManagerBox extends BeanBox {//事务管理器配置,从Spring中抽取的
		{
			setClassOrValue(DataSourceTransactionManager.class);
			setProperty("dataSource", new DSPoolBeanBox());
		}
	}

	static class TxInterceptorBox extends BeanBox {//AOP事务切面处理类,从Spring中抽取的
		{
			Properties props = new Properties();
			props.put("insert*", "PROPAGATION_REQUIRED");
			setConstructor(TransactionInterceptor.class, new TxManagerBox(), props);
		}
	}

	public static class JdbcTemplateBox extends BeanBox {//JDBC模板配置,可换成dbUtils等
		{
			setConstructor(JdbcTemplate.class, new DSPoolBeanBox());
		}
	}
}

public class Tester {//测试类
	@InjectBox
	private JdbcTemplate dao;//注入JdbcTemplateBox配置类生成的实例

	public void insertUser() {
		dao.execute("insert into users values ('User1')");
		int i = 1 / 0; //抛出运行期错误,导致事务回滚
		dao.execute("insert into users values ('User2')");
	}

	public static void main(String[] args) {
		Tester tester = BeanBox.getBean(Tester.class);//从默认上下文获取类实例
		tester.insertUser();
	}
}

示例5中需要额外用到如下第三方包: c3p0-0.9.1.2.jar commons-logging-api-1.0.4.jar mysql-connector-java-5.1.5.jar spring-aop-3.2.16.RELEASE.jar spring-beans-3.2.16.RELEASE.jar spring-core-3.2.16.RELEASE.jar spring-jdbc-3.2.16.RELEASE.jar spring-tx-3.2.16.RELEASE.jar 可从Maven网站按包名搜索下载,或从jBeanBox项目中下载示例项目Demo_jBeanBox2.2.war,其中已包含了以上所有第三方包。

Copyright (c) 2016, Yong Zhu All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the {organization} nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

简介

BeanBox是一个微形(只有单个Java文件约1000行源码)但麻雀虽小功能齐全的IOC/AOP项目,用Java配置代替XML,比目前Spring或Guice的Java配置更简单实用。 jBeanBox的特点: 1)简单,仅一个Java文件实现所有的IOC/AOP功能,无XML,仅1个注解 2)基于类初始化块的Java配置代替XML,其实现比Spring或Guice的Java配置简单且强大。 3)多种注射机制、多配置支持、Bean生命周期支持。 展开 收起
BSD-3-Clause
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/boobor/jBeanBox.git
git@gitee.com:boobor/jBeanBox.git
boobor
jBeanBox
jBeanBox
master

搜索帮助

14c37bed 8189591 565d56ea 8189591