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操作符即可完成注入。
这一篇先吊吊胃口。。下一篇再介绍其全部功能~