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 ...
随机推荐
- Google Intern
申请 事情应该从去年(2013)说起,好基友从百度离职跳到了Google,回学校打印本科成绩单,然后晚上在scuacm群里,结果Dr. zuo问我想去实习么,正好有学长可以内推. 于是乎写了简历,然后 ...
- 编辑器KindEditor的使用
1.具体使用方法看点这里 2.下载点这里 3.文件夹说明 ├── asp asp示例,删掉 ├── asp.net asp.net示例,删掉 ├── attached 空文件夹,放置关联文件attac ...
- [ MongoDB ] 副本集的搭建及测试
Replica Sets 复制 (副本集) node1: 10.0.0.10node2: 10.0.0.11node3: 10.0.0.12 副本集结构图:
- hdu 5190(水题)
Go to movies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- Android 欢迎界面淡入效果并用WebView加载网址
1.首先是欢迎界面布局文件,只有一个背景图片:welcome.xml: <?xml version="1.0" encoding="utf-8"?> ...
- Android InputStream转Bitmap
android socket服务端 接收Delphi socket客户端发来的图片,保存到bitmap中,代码如下: public static Bitmap readInputStreamToBit ...
- a标签实现不跳转点击
<a class="tiao" href="./index.php"></a> JS实现无跳转a标签 <script type=& ...
- 只用120行Java代码写一个自己的区块链-3挖矿算法
在本系列前两篇文章中,我们向大家展示了如何通过精炼的Java代码实现一个简单的区块链.包括生成块,验证块数据,广播通信等等,这一篇让我们聚焦在如何实现 PoW算法. 大家都无不惊呼比特币.以太坊及其他 ...
- virgo-tomcat没有任务错误日志的停掉的解决办法
最近virgo-tomcat总是无缘无故的down掉,用了下面的几种方法来解决这个问题,具体哪个方法生效了,目前还不清楚...1. 删掉了home/logs下面的很大的日志文件 2. 在.bash_p ...
- 25,Spark Sort-Based Shuffle内幕彻底解密
一:为什么需要Sort-Based Shuffle? 1, Shuffle一般包含两个阶段任务: 第一部分:产生Shuffle数据的阶段(Map阶段,额外补充,需要实现ShuffleManager中 ...