不使用框架,如何实现依赖注入

ws-小铁匠 2012-05-25 01:21:13
如题!

求教,谁给说说!

或者发个demo也行,先谢谢了.
...全文
429 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiongyu2006 2012-06-04
  • 打赏
  • 举报
回复
property是name和ref.
xiongyu2006 2012-06-04
  • 打赏
  • 举报
回复
自定义一个ClassPathXmlApplicationContext,在这个类里面通过dom解析xml获取对应节点的id和class,然后通过反射生成对象,把生成的对象都放到map里面去,key是id,value是生成的对象,再获取property的id和class,设置关系。
  • 打赏
  • 举报
回复
通过反射机制。。只要知道类名和包名,就可以new出一个对象出来。。
jdluojing 2012-06-03
  • 打赏
  • 举报
回复
依赖注入的三种方式,接口注入,构造器注入,get/set方法注入。按原理做就可以了。
theoffspring 2012-06-03
  • 打赏
  • 举报
回复
反射创建实例后,强制转换成接口声明的类就行了,什么框架也不用。
s478853630 2012-06-01
  • 打赏
  • 举报
回复
片段代码:


package com.org.mvc2.web;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.org.mvc2.entity.JdbcConfig;
import com.org.mvc2.entity.ModelBean;
import com.org.mvc2.entity.Settled;
import com.org.mvc2.exciption.MvcException;
import com.org.mvc2.model.CacheIdTimer;
import com.org.mvc2.util.ReflectUtil;

/**
* 自定义框架的核心ModelBean和Control
* @version 2.0
* */
public class Mvc2BeanControlServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

/**
* 初始化
* @throws ServletException
* */
public void init() throws ServletException {
String config = getInitParameter(Settled.BEAN_CONTROL_CONFIG);
if (null != config && !"".equals(config)) {
String[] configPath = config.split(",");
for (int i = 0; i < configPath.length; i++) {
if (configPath[i].indexOf("classes") != -1) {
configPath[i] = configPath[i].substring(configPath[i].lastIndexOf("classes") + 8);
}
}
loadConfig(configPath, ReflectUtil.getClasspath());
Long interval = 1000l * 60l * 4l;
new Timer().schedule(new CacheIdTimer(), interval, interval);// 四分钟执行一次
}
}

/**
* 加载配置文件
* @param configPath 配置文件路径,多个文件用数组
* @param basePath class的根目录
* */
@SuppressWarnings("unchecked")
public void loadConfig(String[] configPath, String basePath) {
try {
List<String> packageList = new ArrayList<String>();
if (null != configPath && configPath.length > 0) {
for (int i = 0; i < configPath.length; i++) {
File file = new File(basePath + configPath[i]);
if (!file.exists()) {
throw new MvcException("找不到[" + configPath[i] + "]这个配置文件!");
}
Element root = new SAXReader().read(file).getRootElement();// 根节点
Iterator iterator = root.elements().iterator();
while (iterator.hasNext()) {
Element element = (Element) iterator.next();
if ("context".equals(element.getName())) {
String basePackage = element.attributeValue("basePackage");
if (null == basePackage || "".equals(basePackage)) {
throw new MvcException("配置文件[" + configPath[i] + "]中的context节点必须配置basePackage属性");
}
if (packageList.contains(basePackage)) {
throw new MvcException("多个context节点不能使用相同的basePackage属性值");
}
packageList.add(basePackage);
} else if ("bean".equals(element.getName())) {
String beanName = element.attributeValue("name");
String className = element.attributeValue("class");
if (null == beanName || null == className || "".equals(beanName) || "".equals(className)) {
throw new MvcException("配置文件[" + configPath[i] + "]中的bean节点必须配置name属性和class属性");
}
if (Settled.MODEL_BEAN_CONFIG_MAP.keySet().contains(beanName)) {
throw new MvcException("名称为[" + beanName + "]的javabean已经存在,不能重复设置");
}
ModelBean bean = new ModelBean();
bean.setName(beanName);
bean.setClassName(className);
Object object = Class.forName(className).newInstance();
if (Settled.JDBC_CONFIG_CLASS.equals(className)) {
bean.setObject(ModelBeanWeb.getWeb().loadJdbcProperty(configPath[i], object, element.elementIterator()));
Settled.JDBC_CONFIG_BEAN_MAP.put(beanName, bean);
} else {
bean.setObject(ModelBeanWeb.getWeb().loadProperty(configPath[i], object, element.elementIterator()));
}
Settled.MODEL_BEAN_CONFIG_MAP.put(beanName, bean);
} else {
throw new MvcException("配置文件[" + configPath[i] + "]中有不能解析的配置<" + element.getName() + "/>");
}
}
}
}
ModelBeanWeb.getWeb().loadPackageBean(packageList);
ModelBeanWeb.getWeb().loadForeignObject();
System.out.print("load succeed jdbcEntitys: [");
for (String str : Settled.JDBC_CONFIG_BEAN_MAP.keySet()) {
JdbcConfig config = (JdbcConfig) Settled.JDBC_CONFIG_BEAN_MAP.get(str).getObject();
for (String s : config.getEntityMap().keySet()) {
System.out.print(s + " ");
}
}
System.out.println("]");
System.out.print("load succeed beans: [");
for (String str : Settled.MODEL_BEAN_CONFIG_MAP.keySet()) {
System.out.print(str + " ");
}
for (String str : Settled.MODEL_BEAN_CODE_MAP.keySet()) {
System.out.print(str + " ");
}
System.out.println("]");
System.out.print("load succeed actions: [");
for (String str : Settled.ACTION_MAP.keySet()) {
System.out.print(str + " ");
}
System.out.println("]");
} catch (Exception e) {
e.printStackTrace(); }
}

/**
* get提交
* @param request
* @param response
* @throws ServletException, IOException
* */
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ControlActionWeb.getWeb().execute(request, response);
}

/**
* post提交
* @param request
* @param response
* @throws ServletException, IOException
* */
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ControlActionWeb.getWeb().execute(request, response);
}

}
ws-小铁匠 2012-05-29
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

去看看spring注解的源代码,看懂了,就会写了。spring底层也是通过反射实现ioc的。
[/Quote]

目前对我来说,看spring源码还是很有难度的。

=,=
ws-小铁匠 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 4 楼 的回复:

引用 2 楼 的回复:

那就使用自定义框架吧
http://download.csdn.net/detail/s478853630/4263505
试试看


大哥,下载分好高啊。。。我分不够,555


地球人有句话说:
舍不得孩子,套不着狼
[/Quote]

不是啊,大哥,我分不够啊。。。我想舍得都没机会。


我自己写了个实现方式,等下贴上代码。
本来之前就贴上的,但是不允许连续回复上次,,晕死!
Ajava攻城师 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

去看看spring注解的源代码,看懂了,就会写了。spring底层也是通过反射实现ioc的。
[/Quote]
+1
昨日凡阳 2012-05-28
  • 打赏
  • 举报
回复
去看看spring注解的源代码,看懂了,就会写了。spring底层也是通过反射实现ioc的。
s478853630 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

引用 2 楼 的回复:

那就使用自定义框架吧
http://download.csdn.net/detail/s478853630/4263505
试试看


大哥,下载分好高啊。。。我分不够,555
[/Quote]

地球人有句话说:
舍不得孩子,套不着狼
ws-小铁匠 2012-05-28
  • 打赏
  • 举报
回复
抽象工厂

public interface BeanFactory {

public Object getBean(String name);

}


工厂的实现(核心):

public class XmlBeanFactory implements BeanFactory {

private static XmlBeanFactory xmlBeanFactory;

private Map<String, Object> beans = new HashMap<String, Object>();

private XmlBeanFactory() {
this("beans.xml");
}

public static XmlBeanFactory getInstance() {
if (xmlBeanFactory != null) {
return xmlBeanFactory;
}
xmlBeanFactory = new XmlBeanFactory();
return xmlBeanFactory;
}

public static XmlBeanFactory getInstance(String configurationFile) {
if (xmlBeanFactory != null) {
return xmlBeanFactory;
}
xmlBeanFactory = new XmlBeanFactory(configurationFile);
return xmlBeanFactory;
}

private XmlBeanFactory(String configurationFile) {
try {
SAXReader reader = new SAXReader();
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(configurationFile);
Document document = reader.read(in);

String xPath = "//beans/bean";
List<Node> nodes = document.selectNodes(xPath);

for (Node n : nodes) {
//获取bean节点的id和class,用反射实例化bean,并放到Map里
String name = n.valueOf("@id");
String className = n.valueOf("@class");
Object object = Class.forName(className).newInstance();
this.beans.put(name, object);

List<Node> properties = n.selectNodes("property");
//利用反射实现setter注入依赖
if (properties.size() > 0) {
for (Node property : properties) {
// setter方式注入
String propertyName = property.valueOf("@name");
String propertyValue = property.valueOf("@value");

Object setter = getBean(propertyValue);


//拼凑setXXX方法名
StringBuffer sb = new StringBuffer(propertyName);
sb.replace(0, 1, (propertyName.charAt(0) + "").toUpperCase());
propertyName = "set" + sb.toString();

Method m = object.getClass().getMethod(propertyName,
setter.getClass().getInterfaces());
System.out.println("method name is : " + m.getName());
// 约定:setters方法所决定的属性(property)名,与配置文件中相应的对象命名一致!
m.invoke(object, setter);
}

}
}

} catch (Exception e) {
e.printStackTrace();
}

}

@Override
public Object getBean(String name) {
return beans.get(name);
}

}

在使用时只要将XmlBeanFactory实例化就可以将依赖注入到对应的bean里了,XmlBeanFactory的实例化可以利用servlet在tomcat启动是就初始化了,之后需要bean时,只要从beanFactory拿就可以了。

不知道我表述清楚了没有,希望大伙多给点意见。


缺点:这样并不能实现对servlet注入依赖,因为servlet在被访问时实例化,不受我的管理。我想了好久,没想出个办法来。
ws-小铁匠 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

你下载了别人的资源都还没评论的吧
伸出你那温柔的双手评论一下吧,就有分了。
我的邮箱只有2M的空间,网易很小气啊,没办法咯
[/Quote]

额,是啊,现在想下载评论都没机会,呵呵很少看到免分的资源。

下面我贴上代码,有时间的话,帮看下呗,呵呵,给指出不足之处。
s478853630 2012-05-28
  • 打赏
  • 举报
回复
你下载了别人的资源都还没评论的吧
伸出你那温柔的双手评论一下吧,就有分了。
我的邮箱只有2M的空间,网易很小气啊,没办法咯
ws-小铁匠 2012-05-27
  • 打赏
  • 举报
回复
首先XML配置文件:beans.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans>

<!-- dao -->
<bean id="articleDao" class="com.fjx.cms.dao.impl.ArticleDaoImpl">
</bean>


<!-- service -->
<bean id="articleService"
class="com.fjx.cms.service.impl.ArticleServiceImpl">
<property name="articleDao" value="articleDao"></property>
</bean>

</beans>
ws-小铁匠 2012-05-27
  • 打赏
  • 举报
回复
我自己写了个实现方式,但是还有缺陷,比如,servlet的初始化是tomcat来管理的,我自己来实例化servlet并用setter方式注入依赖,但是在客户端访问servlet时,toncat会自己再实例化servlet,也就是说servlet不受我的控制。

下面贴上代码,大伙帮看看如何改进。
ws-小铁匠 2012-05-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

那就使用自定义框架吧
http://download.csdn.net/detail/s478853630/4263505
试试看
[/Quote]

大哥,下载分好高啊。。。我分不够,555
古布 2012-05-25
  • 打赏
  • 举报
回复
http://syue.com/Software/JAVA/15753.html
http://only1.iteye.com/blog/733550
百度一下,很多的。
s478853630 2012-05-25
  • 打赏
  • 举报
回复
那就使用自定义框架吧
http://download.csdn.net/detail/s478853630/4263505
试试看
ws-小铁匠 2012-05-25
  • 打赏
  • 举报
回复
忘了,我的邮箱: 466516623@qq.com

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧