<?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-2.5.xsd"> <bean id = "injectTestDao" class="test.Inject.InjectTestDao" /> <bean id = "injectTestService" class = "test.Inject.InjectTestServiceImpl" /> </beans>
Bean定义类:
package test.Inject;
import java.util.ArrayList;
import java.util.List;
/**
* xml中的<bean/>的定义
* @author Administrator
*
*/
public class BeanDefinition{
private String id;
private String clazz;
private List<PropertyDefinition> propertyDefinitions=new ArrayList<PropertyDefinition>();
public BeanDefinition(String id, String clazz) {
super();
this.id = id;
this.clazz = clazz;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public List<PropertyDefinition> getPropertyDefinitions() {
return propertyDefinitions;
}
public void setPropertyDefinitions(List<PropertyDefinition> propertyDefinitions) {
this.propertyDefinitions = propertyDefinitions;
}
}
Property定义类用于读取 <bean><property>
package test.Inject;
public class PropertyDefinition {
private String name;
private String ref;
private String value;
public PropertyDefinition(String name, String ref,String value) {
super();
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;
}
}
注释类:
package test.Inject;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
* ElemenetType.CONSTRUCTOR 构造器声明
* ElemenetType.FIELD 域声明(包括 enum 实例)
* ElemenetType.LOCAL_VARIABLE 局部变量声明
* ElemenetType.METHOD 方法声明
* ElemenetType.PACKAGE 包声明
* ElemenetType.PARAMETER 参数声明
* ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
*
* @Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
* RetentionPolicy.SOURCE 注解将被编译器丢弃
* RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
* RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信* 息。
*
* @Documented 将此注解包含在 javadoc 中
* @Inherited 允许子类继承父类中的注解
*
*/
// 在运行时执行
@Retention(RetentionPolicy.RUNTIME)
// 注解适用地方(字段和方法)
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface LwxResource {
//注解的name属性 @LwxResource(name="dddd")
public String name() default "";
}
要注入的类:
package test.Inject;
/**
* @Description: 要注入的Dao类
* @ClassName: InjectTestDao
* @Project: spring-aop
*/
public class InjectTestDao {
public void show(){
System.out.println("这里是dao方法........");
}
}
带有注释的类:
package test.Inject;
/**
* @Description: 带有注解的服务
* @ClassName: InjectTestServiceImpl
* @Project: spring-aop
* @Author: lwx
*/
public class InjectTestServiceImpl {
// 字段上的注解,可以配置name属性
@LwxResource
public InjectTestDao injectTestDao;
// // set方法上的注解,带有name属性
// @LwxResource(name = "injectTestDao")
// public void setInjectTestDao(InjectTestDao injectTestDao) {
// this.injectTestDao = injectTestDao;
// }
public void show() {
injectTestDao.show();
System.out.println("这里是Service方法........");
}
}
注释处理类
package test.Inject;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
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.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/**
* 自定义容器
*
* @author Administrator
*
*/
public class UserDefinedClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
private Map<String, Object> sigletons = new HashMap<String, Object>();
public UserDefinedClassPathXMLApplicationContext(String filename) {
this.readXML(filename);
this.instanceBeans();
this.annotationInject();
this.injectObject();
}
/**
* 读取xml配置文件
*
* @param filename
*/
@SuppressWarnings("all")
private void readXML(String filename) {
SAXReader saxReader = new SAXReader();
Document document = null;
try {
URL xmlPath = this.getClass().getClassLoader()
.getResource(filename);
document = saxReader.read(xmlPath);
XPath xPath = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径。从根路径开始
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");// 加入命名空间
xPath.setNamespaceURIs(nsMap);// 设置命名空间
List<Element> beans = xPath.selectNodes(document);// 获取文档下所有bean节点
for (Element element : beans) {
String id = element.attributeValue("id");
String clazz = element.attributeValue("class");
BeanDefinition beanDefinition = new BeanDefinition(id, clazz);
XPath xPath2 = element.createXPath("ns:property");// 从相对路径开始
xPath2.setNamespaceURIs(nsMap);
List<Element> propertys = xPath2.selectNodes(element);
for (Element element2 : propertys) {
String name = element2.attributeValue("name");
String ref = element2.attributeValue("ref");
String value = element2.attributeValue("value");
PropertyDefinition propertyDefinition = new PropertyDefinition(
name, ref, value);
beanDefinition.getPropertyDefinitions().add(
propertyDefinition);
}
beanDefinitions.add(beanDefinition);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 完成bean的实例化
*/
private void instanceBeans() {
try {
for (BeanDefinition beanDefinition : beanDefinitions) {
if (beanDefinition.getClazz() != null
&& !"".equals(beanDefinition.getClazz().trim())) {
sigletons.put(beanDefinition.getId(), Class.forName(
beanDefinition.getClazz()).newInstance());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 为bean对象的属性注入值
*
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void injectObject() {
try {
for (BeanDefinition beanDefinition : beanDefinitions) {
Object bean = sigletons.get(beanDefinition.getId());
if (bean != null) {
PropertyDescriptor[] ps = Introspector.getBeanInfo(
bean.getClass()).getPropertyDescriptors();
for (PropertyDefinition propertyDefinition : beanDefinition
.getPropertyDefinitions()) {
for (PropertyDescriptor propertyDescriptor : ps) {
if (propertyDefinition.getName().equals(
propertyDescriptor.getName())) {
Method setterMethod = propertyDescriptor
.getWriteMethod();// 获取属性的setter方法
if (setterMethod != null) {
Object temp = null;
if (propertyDefinition.getRef() != null
&& !"".equals(propertyDefinition
.getRef().trim())) {
temp = sigletons.get(propertyDefinition
.getRef());
} else if (propertyDefinition.getValue() != null
&& !"".equals(propertyDefinition
.getValue().trim())) {
temp = ConvertUtils.convert(
propertyDefinition.getValue(),
propertyDescriptor
.getPropertyType());
}
setterMethod.setAccessible(true);// 防止setter方法为private
setterMethod.invoke(bean, temp);// 把引用对象注入到属性
}
break;
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过注解实现注入依赖对象
*
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void annotationInject() {
try {
for (String beanName : sigletons.keySet()) {
Object bean = sigletons.get(beanName);
if (bean != null) {
PropertyDescriptor[] ps = Introspector.getBeanInfo(
bean.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : ps) {
Method setterMethod = propertyDescriptor
.getWriteMethod();
if (setterMethod != null
&& setterMethod
.isAnnotationPresent(LwxResource.class)) {
LwxResource userDefinedResource = setterMethod
.getAnnotation(LwxResource.class);
Object temp = null;
if (userDefinedResource.name() != null
&& !"".equals(userDefinedResource.name())) {
// 一旦指定了name属性,就只能按名称装配了
temp = sigletons
.get(userDefinedResource.name());
} else {
temp = sigletons.get(propertyDescriptor
.getName());
if (temp == null) {
for (String key : sigletons.keySet()) {
if (propertyDescriptor
.getPropertyType()
.isAssignableFrom(
sigletons.get(key)
.getClass())) {
temp = sigletons.get(key);
break;
}
}
}
}
setterMethod.setAccessible(true);
setterMethod.invoke(bean, temp);// 把引用对象注入到属性
}
}
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(LwxResource.class)) {
LwxResource userDefinedResource = field
.getAnnotation(LwxResource.class);
Object temp = null;
if (userDefinedResource.name() != null
&& !"".equals(userDefinedResource.name())) {
temp = sigletons
.get(userDefinedResource.name());
} else {
System.out.println(field.getName());
temp = sigletons.get(field.getName());
if (temp == null) {
for (String key : sigletons.keySet()) {
if (field.getType().isAssignableFrom(
sigletons.get(key).getClass())) {
temp = sigletons.get(key);
break;
}
}
}
}
field.setAccessible(true);// 允许访问private字段
field.set(bean, temp);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取bean实例
*
* @param beanName
* @return
*/
public Object getBean(String beanName) {
return this.sigletons.get(beanName);
}
public static void main(String[] args) {
//读文件的地址是从src下开始读的 也就是 src\test\Inject\injectTest.xml地址
UserDefinedClassPathXMLApplicationContext applicationContext = new UserDefinedClassPathXMLApplicationContext(
"test\\Inject\\injectTest.xml");
InjectTestServiceImpl injectTestService = (InjectTestServiceImpl) applicationContext
.getBean("injectTestService");
injectTestService.show();
}
}