本次主要记录一下spring中的依赖注入。
先来段代码,
package com.xiva.mySpring;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import com.xiva.bean.MyBean;
import com.xiva.bean.PropertyDefinition;
/**
*
* @author XIVA
* @Description 简化的Spring容器
*/
public class XivaContext extends XivaAbsAppContext{
private List<MyBean> beanList = new ArrayList<MyBean>();
private Map<String, Object> sigletons = new HashMap<String, Object>();
private Map<String, PropertyDefinition> property = new HashMap<String, PropertyDefinition>();
public XivaContext(String xmlPath){
this.readXML(xmlPath);
this.instanceBean();
this.injectBean();
}
private void injectBean() {
// TODO Auto-generated method stub
for(Map.Entry<String, PropertyDefinition> map :property.entrySet()){
String key = map.getKey();
PropertyDefinition value = map.getValue();
Object object = sigletons.get(key);
Object injectObject = sigletons.get(value.getRef());
Class<?> clazz = object.getClass();
try{
String methodName = "set" + firToUpper(value.getRef());
Method setMethod = clazz.getMethod(methodName, injectObject.getClass().getInterfaces());
setMethod.invoke(object, injectObject);
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* @Description 解析spring配置文件,初始化bean;其中对bean中配置的property
* @author XIVA
* @param fileName
*/
@SuppressWarnings("unchecked")
private void readXML(String fileName){
SAXReader saxReader = new SAXReader();
Document document = null;
try{
URL xmlPath = this.getClass().getClassLoader().getResource(fileName);
document = saxReader.read(xmlPath);
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");//加入命名空间
XPath xsub = document.createXPath("//ns:beans/ns:bean");//
xsub.setNamespaceURIs(nsMap);//设置命名空间
List<Element> beans = xsub.selectNodes(document);//获取节点
MyBean bean = null;
for (Element element:beans){
String id = element.attributeValue("id");
String clazz = element.attributeValue("class");
if (id!=null && clazz!=null){
bean = new MyBean(id, clazz);
beanList.add(bean);
}
List<Element> pList = element.elements("property");
if (pList != null && pList.size() > 0){
PropertyDefinition propDef = null;
for (Element pEle:pList){
String name = pEle.attributeValue("name");
String ref = pEle.attributeValue("ref");
if (name!=null && ref!=null){
propDef = new PropertyDefinition(name,ref);
property.put(id, propDef);
}
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
*
* @Description 实例化bean
* @author XIVA
*/
private void instanceBean(){
Object object = null;
for(MyBean bean:beanList){
try{
String clazzStr = bean.getBeanClass();
Class<?> clazz = Class.forName(clazzStr);
for(Constructor<?> con:clazz.getDeclaredConstructors()){
con.setAccessible(true);
}
object = clazz.newInstance();
sigletons.put(bean.getBeanId(), object);
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 获取Bean实例
*/
@Override
public Object getBean(String beanName) {
// TODO Auto-generated method stub
return sigletons.get(beanName);
}
/**
* 首字母大写
* @param field
* @return
*/
private static String firToUpper(String field){
String firStr = field.substring(0, 1);
firStr = firStr.toUpperCase();
field = firStr + field.substring(1, field.length());
return field;
}
}
依赖注入,对于Spring的实现有两种;第一种是在构造函数中,来注入外部的类的实例,第二种方式是通过set方法来实例化。当然有了JPA后了,我们又可以通过注解autoware来实现,但是这种原理都是一样的。都是通过类反射,然后找到相应的注解或者解析xml来实现。
/**
*
* @Description 注入
* @author XIVA
*/
private void injectBean() {
// TODO Auto-generated method stub
for (Map.Entry<String, PropertyDefinition> map :property.entrySet()){
String key = map.getKey();
PropertyDefinition value = map.getValue();
Object object = sigletons.get(key);
Object injectObject = sigletons.get(value.getRef());
Class<?> clazz = object.getClass();
try{
String methodName = "set" + firToUpper(value.getRef());
Method setMethod = clazz.getMethod(methodName, injectObject.getClass().getInterfaces());
setMethod.invoke(object, injectObject);
}catch (Exception e){
e.printStackTrace();
}
}
}
上面方法就是通过反射来注入bean的。
List<Element> pList = element.elements("property");
if (pList != null && pList.size() > 0){
PropertyDefinition propDef = null;
for (Element pEle:pList){
String name = pEle.attributeValue("name");
String ref = pEle.attributeValue("ref");
if (name!=null && ref!=null){
propDef = new PropertyDefinition(name,ref);
property.put(id, propDef);
}
}
}
这段代码是解析xml文件中property属性来放入
private Map<String, PropertyDefinition> property = new HashMap<String, PropertyDefinition>();
上面定义的map中。
<bean id="moduleService" class="com.xiva.module.service.impl.ModuleServiceImpl">
<property name="moduleDao" ref="moduleDao"></property>
</bean>
上面的property就是注入。
分享到:
相关推荐
1、spring 的整体架构 2、spring的基本实现(xml的加载原理、标签解析、bean加载) 3、容器扩展 4、ioc和aop 5、事务 6、springmvc 7、dispatcherServlet
网易云课堂黑马Spring四天精通学习笔记&源码(数据库要另建)
spring源码中文注释方便学习,spring源码学习加注释。 spring源码中文注释方便学习,spring源码学习加注释。 spring源码中文注释方便学习,spring源码学习加注释。 spring源码中文...
Spring源码学习笔记,从应用到源码解析深入讲解
spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码spring学习事务源码
Spring源码总结.pdf
spring源码分析专题,源码分析视频,对spring的源码进行分析
Spring Boot学习之Shiro源码【学习狂神说,自己手动书写,可以实现正常所需的功能】 Spring Boot学习之Shiro源码【学习狂神说,自己手动书写,可以实现正常所需的功能】 Spring Boot学习之Shiro源码【学习狂神说,...
struts+hibernate+spring源码学习:hr考勤管理系统.rar
spring源码
spring源码学习
摘自javaEye 学习spring 源码的必备资料. 多多下载
Spring源码学习一:源码分析概述1
这份《Spring源码分析》讲解的非常详细,是基于Spring5的一份讲解,非常值得学习,有兴趣的童鞋可以下载下来看看,保证你们不会浪费这几积分的,绝对超值
SpringBoot源码学习&Spring源码.7z Spring Boot.md 讲解是SpringBoot所有的特性。主要特点,学习笔记, SpringBoot高级.pdf主要是网上共享的一个文档总结Spring的特性,讲的特别简略。 Spring源码.docx主要是讲解...
代码中包括SpringCloud注册中心Eureka服务器,Eureka服务提供者和消费者,Hystrix容错保护、Zuul网关服务等等
基于SpringCloud的在线学习测评系统源码 基于SpringCloud的在线学习测评系统源码 基于SpringCloud的在线学习测评系统源码 基于SpringCloud的在线学习测评系统源码 基于SpringCloud的在线学习测评系统源码 ...
spring5源码学习
spring源码 希望对用spring 框架开发的人有所帮助
马士兵老师spring框架学习笔记