IOC的一种简易实现

Spring源码真长,看着很累。

而且其中稍微有些缺陷,比如万一你必须new一个类,那这个类就得手动调用各setter。

当然,实现ApplicationContextAware后再取出bean也可以。总觉得稍显麻烦。

毕竟,java本身只有简单纯粹的语法,没有各式各样的框架。而创建一个类最简单的方法自然就是使用 new 。

如果使用new创建的对象也能直接实现 inversion of control,dependency injection该多好!


于是我花了不到两天时间做了一个小工具。目前处于Alpha阶段

目前放在我的github上,有兴趣可以看一看~~源码暂时公开最核心的两个类。

https://github.com/wkgcass/toolbox/          其中ioc就是这个工具。

(2月27更新:现在开始了一个与其并行的项目,用法与其一致,并且同样可在任何环境运行,取消了对bean的支持,专注于最纯粹的代码,稳定性很高。项目目前名称定为Purify 。Github 在 https://github.com/wkgcass/purify ,但是还没有公开代码)


实现的逻辑很清晰,但谁整天喜欢看逻辑呢~

还是先看看它能做什么吧!

1.和struts2协作运行:

UserService

public class UserService extends AutoWire{
	private User user;
	
	public String execute() throws Exception{
		System.out.println(user.getData());
		return "success";
	}

	public void setUser(User user) {
		this.user = user;
	}

	public User getUser() {
		return user;
	}
}

User

@Wire
public class User {
	private DataAccess data;

	public void setData(DataAccess data) {
		this.data = data;
	}

	public DataAccess getData() {
		return data;
	}
}

由于是测试,所以这里仅仅向控制台输出UserService实例中的user对象的data对象,以检验是否注入成功。

运行,结果:

test.DataAccess@c272bc

也就是说完成了多层注入。


2.循环依赖

Circular0

public class Circular0 extends AutoWire {
	private Circular1 c1;

	public void setC1(Circular1 c1) {
		this.c1 = c1;
	}

	public Circular1 getC1() {
		return c1;
	}
}

Circular1

@IsSingleton
public class Circular1 extends AutoWire {
	private Circular2 c2;

	public void setC2(Circular2 c2) {
		this.c2 = c2;
	}

	public Circular2 getC2() {
		return c2;
	}
}

Circular2

@IsSingleton
public class Circular2  extends AutoWire {
	private Circular1 c1;

	public void setC1(Circular1 c1) {
		this.c1 = c1;
	}

	public Circular1 getC1() {
		return c1;
	}
}
上面可以看到,Circular1和Circular2互相引用,而且两者都被标记为IsSingleton

调用:

Circular0 c0=new Circular0();
Thread.sleep(1);
System.out.println(c0.getC1().getC2());
运行结果:

test.Circular2@6d084b

可以看出,循环注入已经完成了。

这里的Thread.sleep(1)是为了让注入完成而设置的,这是由于实现方式造成的一点小瑕疵,后续版本中我会作逻辑上的修复。

(2月27日更新:purify项目中无需任何多余操作即可完成循环依赖注入)


3.使用“bean”,使用带参数的constructor

这个工具允许定义自己的bean,只需用注解标注在类前。

允许构造器带参数,允许指定使用哪一个构造器

ManipUserDAO

public class ManipUserDAO extends AutoWire {
	private UserDAO userDAO;
	private Circular0 c0;
	private int i;
	@Use(bean="hehe")
	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setC0(Circular0 c0) {
		this.c0 = c0;
	}

	public Circular0 getC0() {
		return c0;
	}
}

UserDAO

@Bean(name={"dao","hehe"})
@Wire
public class UserDAO {
	private int id=100;
	private String name;
	private String pwdMd5;
	private DatabaseAccess da;
	@Default(bean="hehe")
	public UserDAO(DatabaseAccess da){
		this.da=da;
	}
	public UserDAO(){
		id=2;
	}
	public int getId() {
		return id;
	}
	
	public String getName() {
		return name;
	}
	
	public String getPwdMd5() {
		return pwdMd5;
	}
	public DatabaseAccess getDa() {
		return da;
	}
	
}

调用:

ManipUserDAO manipUserDAO=new ManipUserDAO();
Thread.sleep(1);
System.out.println(manipUserDAO.getC0().getC1().getC2()+"    "+manipUserDAO.getUserDAO().getDa());

运行结果

test.Circular2@6d084b    test.DatabaseAccess2@3bb2b8

全部成功构造/注入。


===============================================================


根据上述过程,想必大家已经大概了解应该怎么使用了。而且,其功能并没有想象中那么弱小。

而大部分情况下,使用都是极其方便的。继承AutoWire类后,仅仅使用原生的new操作符即可完成注入。

这一篇先吊吊胃口。。下一篇再介绍其全部功能~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值