Spring(八)编码剖析@Resource注解的实现原理
配置文件beans2.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" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 把针对注解的容器注射到Spring容器中 -->
<context:annotation-config />
<bean id="personDaoxx" class="test.spring.dao.impl.PersonDaoBean" />
<!-- <bean id="personService" class="test.spring.service.impl.PersonServiceBean4"></bean> -->
<bean id="personService" class="test.spring.service.impl.PersonServiceBean3"></bean>
</beans>
package test.spring.dao;
public interface PersonDao {
public abstract void add();
}
package test.spring.dao.impl;
import test.spring.dao.PersonDao;
public class PersonDaoBean implements PersonDao {
@Override
public void add(){
System.out.println("执行PersonDaoBean里的test1()方法");
}
}
package test.spring.service;
public interface PersonService2 {
public abstract void save();
}
package test.spring.service.impl;
import test.spring.dao.PersonDao;
import test.spring.jnit.AnnotationTest;
import test.spring.service.PersonService2;
public class PersonServiceBean3 implements PersonService2 {
private PersonDao personDao;
private String name;
public PersonServiceBean3() {
}
public PersonServiceBean3(PersonDao personDao, String name) {
this.personDao = personDao;
this.name = name;
}
public PersonDao getPersonDao() {
return personDao;
}
@AnnotationTest
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void save() {
// TODO Auto-generated method stub
personDao.add();
// System.out.println(name);
}
}
package test.spring.jnit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.dom4j.Element;
//选择在执行期
@Retention(RetentionPolicy.RUNTIME)
// 指定注解仅仅能用在字段和方法上
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface AnnotationTest {
public String name() default "";
}
package test.spring.jnit;
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;
import test.spring.entity.Bean2;
import test.spring.entity.Property;
public class AnnotationInjectTest {
private List<Bean2> beanDefines = new ArrayList<Bean2>();
private Map<String, Object> singletons = new HashMap<String, Object>();
public AnnotationInjectTest(String filename) {
this.readXML(filename);
this.instanceBeans();
this.injectObject();
this.annotationInject();
}
private void annotationInject() {
// TODO Auto-generated method stub
for (String beanName : singletons.keySet()) {
Object bean = singletons.get(beanName);
if (bean != null) {
try {
PropertyDescriptor[] pDescriptors = Introspector
.getBeanInfo(bean.getClass())
.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : pDescriptors) {
Method setter = propertyDescriptor
.getWriteMethod();
if (setter != null
&& setter
.isAnnotationPresent(AnnotationTest.class)) {
AnnotationTest aTest = setter
.getAnnotation(AnnotationTest.class);
Object value = null;
if (aTest.name() != null
&& !"".equals(aTest.name())) {
value = singletons.get(aTest.name());
setter.setAccessible(true);
try {
setter.invoke(bean, value);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} 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);
try {
setter.invoke(bean, value);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(AnnotationTest.class)) {
AnnotationTest aTest = field
.getAnnotation(AnnotationTest.class);
Object value = null;
if (aTest.name() != null
&& !"".equals(aTest.name())) {
value = singletons.get(aTest.name());
} else {
value = singletons.get(field.getName());
if (value == null) {
for (String key : singletons.keySet()) {
if (field.getType().isAssignableFrom(
singletons.get(key).getClass())) {
value = singletons.get(key);
break;
}
}
}
}
field.setAccessible(true);
try {
field.set(bean, value);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
}
}
/**
* 为bean对象的属性注入值
*/
private void injectObject() {
for (Bean2 beanDefinition : beanDefines) {
Object bean = singletons.get(beanDefinition.getId());
if (bean != null) {
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(
bean.getClass()).getPropertyDescriptors();
for (Property propertyDefinition : beanDefinition
.getProperties()) {
for (PropertyDescriptor properdesc : ps) {
if (propertyDefinition.getName().equals(
properdesc.getName())) {
java.lang.reflect.Method setter = properdesc
.getWriteMethod();// 获取属性的setter方法
// ,private
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(),
properdesc.getPropertyType());
}
setter.setAccessible(true);
setter.invoke(bean, value);// 把引用对象注入到属性
}
break;
}
}
}
} catch (Exception e) {
}
}
}
}
/**
* 完毕bean的实例化
*/
private void instanceBeans() {
for (Bean2 beanDefinition : beanDefines) {
try {
if (beanDefinition.getClassPath() != null
&& !"".equals(beanDefinition.getClassPath().trim()))
singletons.put(beanDefinition.getId(),
Class.forName(beanDefinition.getClassPath())
.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 读取xml配置文件
*
* @param filename
*/
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");// 创建beans/bean查询路径
xsub.setNamespaceURIs(nsMap);// 设置命名空间
List<Element> beans = xsub.selectNodes(document);// 获取文档下全部bean节点
for (Element element : beans) {
String id = element.attributeValue("id");// 获取id属性值
String clazz = element.attributeValue("class"); // 获取class属性值
Bean2 beanDefine = new Bean2(id, clazz);
XPath propertysub = element.createXPath("ns:property");
propertysub.setNamespaceURIs(nsMap);// 设置命名空间
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");
Property propertyDefinition = new Property(propertyName,
propertyref, propertyValue);
beanDefine.getProperties().add(propertyDefinition);
}
beanDefines.add(beanDefine);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取bean实例
*
* @param beanName
* @return
*/
public Object getBean(String beanName) {
return this.singletons.get(beanName);
}
}
package test.spring.jnit;
import org.junit.Test;
import test.spring.service.PersonService2;
public class SpringTest4 {
@Test
public void testAnnotationInject() {
AnnotationInjectTest applicationContext = new AnnotationInjectTest(
"beans2.xml");
PersonService2 personService = (PersonService2) applicationContext
.getBean("personService");
personService.save();
}
}
待续
Spring(八)编码剖析@Resource注解的实现原理的更多相关文章
- (转)编码剖析@Resource注解的实现原理
http://blog.csdn.net/yerenyuan_pku/article/details/52860046 上文我们已经学会使用@Resource注解注入属性.学是学会了,但也仅限于会使用 ...
- Spring2.5学习3.2_编码剖析@Resource注解的实现原理
首先看一下J2EE提供的@Resource注解:该注解默认安照名称进行装配,名称能够通过name属性进行指定, 假设没有指定name属性,当注解写在字段上时,默认取字段名进行依照名称查找,假设注解写在 ...
- Spring、编码剖析Spring管理Bean的原理
引入dom4j jar包 1.新建Person接口和PersonBean public interface PersonIService { public void helloSpring(); } ...
- Spring源码剖析7:AOP实现原理详解
前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...
- Spring第七弹—依赖注入之注解方式注入及编码解析@Resource原理
注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果. 手工装配依赖对象 手工装配依赖对象,在这种方式中又有两种编 ...
- 编码实现Spring 利用@Resource注解实现bean的注入,xml实现基本数据类型的注入
首先分析. 1: 肯定要利用dom4j读取xml配置文件,将所有的bean的配置信息读取出来 2: 利用反射技术,实例化所有的bean 3: 写注解处理器, 利用注解和内省实现依赖对象的注入. 4: ...
- Spring中@Autowired注解、@Resource注解的区别
Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...
- 转:Spring中@Autowired注解、@Resource注解的区别
Pay attention: When using these annotations, the object itself has to be created by Spring context. ...
- Spring中 @Autowired注解与@Resource注解的区别
Spring中 @Autowired注解与@Resource注解的区别在Spring 3.X中经常使用到@Autowired和@Resource进行装配.这两个注解的差异在何处???相同点:@Reso ...
随机推荐
- C++格式输出控制
#include<iostream> #include<string> #include<vector> #include<set> #include& ...
- 【计算机网络】wireshark抓包分析2
在分析1中,大概的看到了一个包中的信息.这里,看看这些包究竟在做什么 这是我的电脑跟某个网站交互的前4个包. 其中前三个包可以明显看出是TCP的三次握手. 那么,问题来了: 为什么第三个包的长度比前两 ...
- MongoDB走过的坑(4.0.3版本)
数据存储一般使用本地或者存储在数据库,MongoDB是一个非关系型数据库,今天小结下走过的一些坑. 1.网上的很多教程对自己无效 解决方法:这种情况一般都是和版本有关系,数据库在不断的更新发展,很多东 ...
- Manacher【p1210】回文检测
题目描述--->P1210 回文检测 分析: 看到回文显然想到了manacher算法(线性求解回文串问题 如果不了解还是去敲一下板子,学习一下比较好.-->manacher 题目要求我们求 ...
- 改变jenkins主目录
jenkins主目录默认是运行在当前用户的家目录下,如: /home/heboan/.jenkins 因为随着jenkins项目的情况,这个目录会变得越来越大,当我的家目录空间不够大的时候就要考虑把主 ...
- Android开机过程
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha Android开机过程 BootLoder引导,然后加载Linux内核. 0号进程ini ...
- 【离线】【递推】【multiset】 Codeforces Round #401 (Div. 2) C. Alyona and Spreadsheet
对询问按右端点排序,对每一列递推出包含当前行的单调不下降串最多向前延伸多少. 用multiset维护,取个最小值,看是否小于等于该询问的左端点. #include<cstdio> #inc ...
- 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行
树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...
- STL之priority_queue2
描述 使用STL中的优先队列,将一个字符串中的各个字符按照ASCII从小到大顺序排列. 部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码. int main() { int n; cin&g ...
- 【OpenJudge9267】【递推】核电站
核电站 总时间限制: 5000ms 单个测试点时间限制: 1000ms 内存限制: 131072kB [描述] 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆 ...