之前我们都是介绍如何注入依赖对象类型的,那么如何注入基本类型呢?
例如:
private String name;
我们如何给 name 属性注入值?
1、修改 PresonServiceImpl 类,代码如下:
package com.learn.service.impl;
import com.learn.dao.PresonDao;
import com.learn.service.PresonService;
/**
* 业务层
* @author Administrator
*
*/
public class PresonServiceImpl implements PresonService {
private PresonDao presonDao;
private String name;
private Integer id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public PresonDao getPresonDao() {
return presonDao;
}
public void setPresonDao(PresonDao presonDao) {
this.presonDao = presonDao;
}
/* (non-Javadoc)
* @see com.learn.service.impl.PresonService#save()
*/
@Override
public void save(){
System.out.println("id="+id+",name="+name);
presonDao.add();
}
}
2、修改 XML文件,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="personService" class="com.learn.service.impl.PresonServiceImpl">
<property name="presonDao">
<bean class="com.learn.dao.impl.PresonDaoImpl"/>
</property>
<property name="name" value="hwl"/>
<property name="id" value="99"/>
</bean>
</beans>
3、测试。
4、以上功能的实现原理,如下:
(1)、修改 PropertyDefinition 类, 代码如下:
package junit.test;
/**
* 用于存放xml文件中 property 元素的信息
* @author Administrator
*
*/
public class PropertyDefinition {
//以下变量表示 property 元素中的属性,并用于存放属性值
private String name;
private String ref;
private String value;
//构造函数
public PropertyDefinition(String name, String ref, String value) {
this.name = name;
this.ref = ref;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
(2)、http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi 下载commons-beanutils,导入 commons-beanutils-1.8.3.jar
(3)、修改 TestClassPathXMLApplicationContext 类,代码如下:
package junit.test;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
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.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/**
* 模拟spring
* @author Administrator
*
*/
public class TestClassPathXMLApplicationContext {
List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
Map<String, Object> sigletons = new HashMap<String, Object>();
public TestClassPathXMLApplicationContext(String filename){
readFile(filename);
instanceBeans();
injectObj();
}
/**
* 为 bean 对象属性注入值
*/
private void injectObj() {
for(BeanDefinition beanDefinition : beanDefines){
//通过 id 得到 bean 元素所指向的类
Object bean = sigletons.get(beanDefinition.getId());
if(null != bean){ //判断类是否存在
try{
// 得到类的属性描述
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDefinition propertyDefinition : beanDefinition.getProperty()){
for(PropertyDescriptor propertydesc : ps){
if(propertyDefinition.getName().equals(propertydesc.getName())){
//获取属性的setter方法
Method setter = propertydesc.getWriteMethod();
if(null != setter){ //容错处理
Object value = null;
/**
* 判断 ref 是否存在,如果存在则注入依赖对象,否则注入基本类型
*/
if(null != propertyDefinition.getRef() && !"".equals(propertyDefinition.getRef())){
value = sigletons.get(propertyDefinition.getRef());
}else{
value = ConvertUtils.convert(propertyDefinition.getValue(), propertydesc.getPropertyType());
}
setter.setAccessible(true); //如果setter方法是私有的,经调用该方法处理表示可以访问
setter.invoke(bean, value);
}
break;
}
}
}
}catch(Exception e){
}
}
}
}
/**
* 实例化bean对象
*/
private void instanceBeans() {
for(BeanDefinition beanDefinition : beanDefines){
try {
/**
* 通过反射技术将bean实例化
*/
if(null != beanDefinition.getClassName() && !"".equals(beanDefinition.getClassName().trim())){
sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 读取xml文件
* @param filename
*/
private void readFile(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>();
//加入命名空间,xml 文件中的命名空间为 xmlns="http://www.springframework.org/schema/beans" ,我们这里将它放入到ns中
nsMap.put("ns", "http://www.springframework.org/schema/beans");
//创建beans/bean查询路径,通过命名空间找到,该命名空间下的节点元素
XPath xsub = document.createXPath("//ns:beans/ns:bean");
//设置命名空间
xsub.setNamespaceURIs(nsMap);
//获取文档下所有的bean节点
@SuppressWarnings("unchecked")
List<Element> beans = xsub.selectNodes(document);
for(Element element : beans){
String id = element.attributeValue("id");
String className = element.attributeValue("class");
BeanDefinition beanDefine = new BeanDefinition(id, className);
//创建查询路径
XPath propertysub = element.createXPath("ns:property");
//设置命名空间
propertysub.setNamespaceURIs(nsMap);
//获取当前元素下的节点
@SuppressWarnings("unchecked")
List<Element> propertys = propertysub.selectNodes(element);
for(Element property : propertys){
String propertyName = property.attributeValue("name");
String propertyRef = property.attributeValue("ref");
String propertyValue = property.attributeValue("value");
PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyRef, propertyValue);
beanDefine.getProperty().add(propertyDefinition);
}
beanDefines.add(beanDefine);
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 获取bean实例
* @param beanName
* @return
*/
public Object getBean(String beanName){
return sigletons.get(beanName);
}
public void initStr(){
System.out.append("ff");
}
}
if(null != propertyDefinition.getRef() && !"".equals(propertyDefinition.getRef())){
value = sigletons.get(propertyDefinition.getRef());
}else{
value = ConvertUtils.convert(propertyDefinition.getValue(), propertydesc.getPropertyType());
}
首先,判断 ref 是否存在,如果存在则注入依赖对象,否则注入基本类型;ConvertUtils.convert() 方法来自之前导入的jar,作用是:将得到的值转化为所要的类型。
(4)、修改 TestSpring 类,测试。代码如下:
package junit.test;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.learn.service.PresonService;
public class TestSpring {
@Test
public void initContainerSpring() {
TestClassPathXMLApplicationContext ctx = new TestClassPathXMLApplicationContext("com//learn//spring//learn1.xml");
PresonService personService = (PresonService)ctx.getBean("personService");
personService.save();
}
}
XML 文件不变。
浙公网安备 33010602011771号