模拟spring,自定义容器二(注解实现属性注入)
来源:互联网 发布:知乎童谣诈骗事件介绍 编辑:程序博客网 时间:2024/06/06 07:43
1.创建自定义的容器类(增加自定义注解)
package cn.hq.customspring;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Field;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.Element;import org.dom4j.XPath;import org.dom4j.io.SAXReader;/** * 自定义的spring容器 * */public class HqClasspathXmlApplicationContext {private List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();private Map<String,Object> singletons = new HashMap<String,Object>();public HqClasspathXmlApplicationContext(String filename) {this.readXML(filename);this.instanceBeans();this.annotationInject();this.injectObject();}/** * 自定义注解注入 */private void annotationInject() {for(String beanName : singletons.keySet()) {Object bean = singletons.get(beanName);if(bean!=null) {try {PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();//setter方法上有注解for(PropertyDescriptor propertyDescriptor : ps) {Method setter = propertyDescriptor.getWriteMethod();if(setter!=null && setter.isAnnotationPresent(HqResource.class)) { //setter上有HqResource注解HqResource resource = setter.getAnnotation(HqResource.class);Object value = null;if(resource.name() !=null&& !"".equals(resource.name())) {value = singletons.get(resource.name());}else {value = singletons.get(propertyDescriptor.getName());if(value == null) {for(String key : singletons.keySet()) {//判断类型是否相同if(propertyDescriptor.getPropertyType().isAssignableFrom(singletons.get(key).getClass())) {value = singletons.get(key);break;}}}}setter.setAccessible(true);setter.invoke(bean, value);}}//属性上有注解Field[] fields = bean.getClass().getDeclaredFields();for(Field field: fields) {if(field.isAnnotationPresent(HqResource.class)) {HqResource resource = field.getAnnotation(HqResource.class);Object value = null;if(resource.name() !=null&& !"".equals(resource.name())) {value = singletons.get(resource.name());}else {value = singletons.get(resource.name());if(value == null) {for(String key : singletons.keySet()) {//判断类型是否相同if(field.getType().isAssignableFrom(singletons.get(key).getClass())) {value = singletons.get(key);break;}}}}field.setAccessible(true);field.set(bean, value);}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}//为bean对象的属性注入值private void injectObject() {for(BeanDefinition beanDefinition : beanDefinitions) {Object bean = singletons.get(beanDefinition.getId());if(bean!=null) {try {PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()) {for(PropertyDescriptor propertyDescriptor : ps) {if(propertyDefinition.getName().equals(propertyDescriptor.getName())) {Method setter = propertyDescriptor.getWriteMethod(); //获取属性的set方法if(setter != null) {Object value = null;if(propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())) {value = singletons.get(propertyDefinition.getRef());}else {value = ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor.getPropertyType());}setter.setAccessible(true); // 设置为true 以防属性为privatesetter.invoke(bean, value); //将引用对象注入到属性}}}}} catch (Exception e) {e.printStackTrace();}}}}//完成Bean实例化private void instanceBeans() {for(BeanDefinition beanDefinition : beanDefinitions) {try {if(beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) {singletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());}} catch (Exception e) {e.printStackTrace();} }}//读取XML文件中的bean @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 xPath = document.createXPath("//ns:beans/ns:bean"); //创建beans和bean查询路劲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);//读取bean的属性property节点XPath xPathProperty = element.createXPath("ns:property"); //xPathProperty.setNamespaceURIs(nsMap); //设置命名空间List<Element> propertys = xPathProperty.selectNodes(element);for(Element property : propertys) {String propertyName = property.attributeValue("name");String propertyRef = property.attributeValue("ref");String propertyValue = property.attributeValue("value");//System.out.println("name=" + propertyName + "-----ref=" + propertyRef);PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyRef,propertyValue);beanDefinition.getPropertys().add(propertyDefinition);}beanDefinitions.add(beanDefinition);}} catch (Exception e) {e.printStackTrace();}}/** * 获取bean实例 * @param beanName * @return */public Object getBean(String beanName) {return singletons.get(beanName);}}
2.自定义注解类
package cn.hq.customspring;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 自定义注解类 */@Retention(RetentionPolicy.RUNTIME) //运行时期@Target({ElementType.FIELD,ElementType.METHOD}) //注解作用在字段上和方法上public @interface HqResource {public String name() default "";}
3.使用自定义注解
package cn.hq.service.impl;import cn.hq.customspring.HqResource;import cn.hq.dao.StudentDao;import cn.hq.service.StudentService;public class StudentServiceImpl implements StudentService{@HqResourceprivate StudentDao studentDao;public void setStudentDao(StudentDao studentDao) {this.studentDao = studentDao;}public void save() throws Exception {System.out.println("studentServiceImpl==>save()");studentDao.add();}public void init() throws Exception {System.out.println("studentServiceImpl==>init()");}public void destroy() throws Exception {System.out.println("studentServiceImpl==>destroy()");}}
4.测试
HqClasspathXmlApplicationContext hqApplicationContext = new HqClasspathXmlApplicationContext("beans.xml");StudentService studentService = (StudentService)hqApplicationContext.getBean("studentService");try {studentService.save();} catch (Exception e) {e.printStackTrace();}
阅读全文
0 0
- 模拟spring,自定义容器二(注解实现属性注入)
- 模拟spring,自定义容器一(属性注入、Bean的实例化)
- spring注解注入属性
- spring 注解实现注入
- Spring注解来注入属性
- 使用Spring注解注入属性
- 使用spring注解注入属性
- Spring 之 编码实现 @Resource注解属性注入
- Spring:IOC释义(Bean容器、注解、依赖注入)
- spring 注入方式二:注解
- 依赖注入(DI)和控制反转(IOC)的详细讲解 spring容器(spring注解实现,而不是xml配置文件)
- Spring总结(二) 属性注入
- Spring实战-注入Bean属性(二)
- 模拟spring依赖注入,自定义注入类
- (二)spring的注入---配置构造器属性注入
- Spring的bean管理(注解注入属性)
- 模仿Spring实现注解注入
- 使用Spring注解来注入属性
- jQuery-Selectors(选择器)的使用(七、子元素篇)
- 10.11 NOIP模拟赛 DP + 线段树 + DP + 单调队列
- jQuery-Selectors(选择器)的使用(八、表单篇)
- POJ1039 激光照管子
- eclipse及idea常用快捷键
- 模拟spring,自定义容器二(注解实现属性注入)
- 【模板】KMP
- 最长递增子序列问题
- 10倍效率的开发人员习惯
- 如何用业余时间掌握前端开发?
- JavaScript 字符串转数字:陷阱(示例)
- strategy pattern
- 试题库问题
- 让Git的输出更友好: 多种颜色和自定义log格式