- 浏览: 807070 次
- 性别:
- 来自: 西安
文章分类
- 全部博客 (307)
- struts (8)
- hibernate (3)
- spring (32)
- opensourceproject (12)
- javaScript (9)
- primeton EOS (2)
- journey of heart (10)
- Design pattern (6)
- ejb (17)
- point (37)
- Linux&Unix (22)
- ibatis (10)
- AJAX (6)
- DB (26)
- Protocol (6)
- chart (4)
- web server (11)
- webservice (7)
- integration (3)
- tuxedo (5)
- ext (4)
- android (1)
- c/c++ (12)
- JVM (1)
- paginationFrame (2)
- code (2)
- report (1)
- High-performance web (1)
- svn (1)
- JQuery (1)
- workDaily (2)
- cloud (16)
- Python (8)
- English (2)
- shell (5)
- googleCode (1)
- nio (1)
- hyper-v (1)
- debug (3)
- vbs (2)
- openstack (3)
- K8S (1)
- Mesos (0)
- Spark (0)
- Marathon (0)
最新评论
-
钱图大展:
chao2751021 写道lib包哪里去下载,找不到
大型网站用户行为记录的一个实现--基于clickStream(第一部分) -
钱图大展:
无法下载
大型网站用户行为记录的一个实现--基于clickStream(第一部分) -
fm395728572:
shell脚本中用到了环境变量,但是获取不到,例如脚本中有一句 ...
ganymed-ssh2 for Java -
liuhanjiang:
我qq147229234
大型网站用户行为记录的一个实现--基于clickStream(第一部分) -
liuhanjiang:
博主 我利用您提供的方法实现博文中介绍的clickstream ...
大型网站用户行为记录的一个实现--基于clickStream(第一部分)
在这一讲开始之前,我们先学习一下jdk5.0 中的一个新特性: 注解
首先转载两篇文章:
如果使用了JSR-250中的注解,如@Resource/@PostConstruct/@PreDestroy,还需要下列jar文件
lib\j2ee\common-annotations.jar
下面我们继续改造我们自己实现的spring容器 (传智播客版spring容器)ItcastClassPathXMLApplicationContext.,完成类似的使用注解完成依赖对象的注入
步骤:
(1)首先创建一个自己的注解 ItcastResource ,类似上一讲的 Resource注解
package junit.test; 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 ItcastResource { public String name() default ""; //注解的默认name值是"" }
@Retention(RetentionPolicy.RUNTIME)
RUNTIME表示在源码、编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的
@Target({ElementType.FIELD, ElementType.METHOD})
@Target里面的ElementType是用来指定Annotation类型可以用在哪一些元素上的.说明一下:TYPE(类型), FIELD(属性), METHOD(方法), PARAMETER(参数), CONSTRUCTOR(构造函数),LOCAL_VARIABLE(局部变量), ANNOTATION_TYPE,PACKAGE(包),其中的TYPE(类型)是指可以用在Class,Interface,Enum和Annotation类型上.
(2)将 PersionServiceBean 中的Resource注解 换成我们自己的 ItcastResource 注解
(3) 修改仿spring容器 ,也就是传智播客容器 ItcastClassPathXMLApplicationContext
package junit.test; 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; /** * 传智传客版容器 * */ public class ItcastClassPathXMLApplicationContext { private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>(); private Map<String, Object> sigletons = new HashMap<String, Object>(); public ItcastClassPathXMLApplicationContext(String filename){ this.readXML(filename); this.instanceBeans(); this.annotationInject(); this.injectObject(); } /** * 通过注解实现注入依赖对象 */ private void annotationInject() { for(String beanName : sigletons.keySet()){ Object bean = sigletons.get(beanName); if(bean!=null){ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDescriptor properdesc : ps){ Method setter = properdesc.getWriteMethod();//获取属性的setter方法 /*如果setter方法不为空,并且上面有注解*/ if(setter!=null && setter.isAnnotationPresent(ItcastResource.class)){ /*得到注解*/ ItcastResource resource = setter.getAnnotation(ItcastResource.class); Object value = null; //如果注解的name属性不为空,也就是这种情况 @ItcastResource(name="persionDao") if(resource.name()!=null && !"".equals(resource.name())){ value = sigletons.get(resource.name()); }else{ /*如果注解的name为空,则根据属性的名字来得到bean*/ value = sigletons.get(properdesc.getName()); if(value==null) { /*如果的得到的bean为空,则根据key遍历容器中所有的bean,如果发现和属性类型相同的bean,就开始注入*/ for(String key : sigletons.keySet()){ if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){ value = sigletons.get(key); break; } } } } setter.setAccessible(true); setter.invoke(bean, value);//把引用对象注入到属性 } } /*对字段处理,也就是字段上有注解的情况*/ Field[] fields = bean.getClass().getDeclaredFields(); for(Field field : fields){ if(field.isAnnotationPresent(ItcastResource.class)){ ItcastResource resource = field.getAnnotation(ItcastResource.class); Object value = null; if(resource.name()!=null && !"".equals(resource.name())){ value = sigletons.get(resource.name()); }else{ value = sigletons.get(field.getName()); if(value==null){ for(String key : sigletons.keySet()){ if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){ value = sigletons.get(key); break; } } } } field.setAccessible(true);//允许访问private字段 field.set(bean, value); } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 为bean对象的属性注入值 */ private void injectObject() { for(BeanDefinition beanDefinition : beanDefines){ Object bean = sigletons.get(beanDefinition.getId()); if(bean!=null){ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){ for(PropertyDescriptor properdesc : ps){ if(propertyDefinition.getName().equals(properdesc.getName())){ Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private if(setter!=null){ Object value = null; if(propertyDefinition.getRef()!=null && !"".equals(propertyDefinition.getRef().trim())){ value = sigletons.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(BeanDefinition beanDefinition : beanDefines){ try { if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).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属性值 BeanDefinition beanDefine = new BeanDefinition(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"); PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref, propertyValue); beanDefine.getPropertys().add(propertyDefinition); } beanDefines.add(beanDefine); } }catch(Exception e){ e.printStackTrace(); } } /** * 获取bean实例 * @param beanName * @return */ public Object getBean(String beanName){ return this.sigletons.get(beanName); } }
(4) 测试 将@ItcastResource(name="persionDao") 放在字段或者相应的setter方法上两种情况
ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml");
PersionSevice ps=(PersionSevice)ctx.getBean("persionServiceBean");
ps.save();
(5)结果
INFO (PersionServiceBean.java:19) - 我被实例化了
INFO (PersionDaoBean.java:15) - 执行了PersionDaoBean中的add()方法
发表评论
-
hibernatetemplate类使用
2010-03-19 22:25 1201http://115893520.iteye.com/blog ... -
Spring 中的JdbcTemplate使用
2010-03-19 22:11 35021.JdbcTemplate的execute()方 ... -
SpringAOP 的使用(两种方式)
2009-10-22 13:42 1519使用Spring AOP 拦截 方法,给被拦截的 ... -
第30讲--Spring提供的CharacterEncoding和OpenSessionInView功能
2009-09-19 18:24 1790CharacterEncoding: 在web ... -
第29讲--为Spring集成的Hibernate配置二级缓存
2009-09-18 00:29 3399合理的使用缓存策略,往往在web开发中提高性能起到关键 ... -
第28讲--Struts与Spring集成方案2(Spring集成Struts)
2009-09-17 00:57 1635集成步骤: 1.和方案1一样需要在web. ... -
第27讲--Struts与Spring集成方案1(Struts集成Spring)
2009-09-16 08:25 1827Spring2.5+Hibernate3.3+Stru ... -
第25,26讲 --搭建和配置Spring与Hibernate整合的环境
2009-06-21 11:21 1605Spring2.5+Hibernate3.3+Stru ... -
第24讲 --使用Spring配置文件实现事务管理
2009-06-20 23:56 1767采用基于XML方式配置事务 <bean ... -
第23讲 --使用Spring注解方式管理事务与传播行为详解
2009-06-11 23:19 2249事务传播属性 REQUIR ... -
第21,22讲 --搭建和配置Spring与jdbc整合的环境+Spring集成的jdbc编码和事务
2009-06-10 08:06 2701Spring+JDBC组合开发配置数据源有两种方式: ... -
第20讲--aspectj的切入点语法定义细节
2009-06-06 17:47 3641表达式分析: expression=" ... -
第19讲 --使用Spring配置文件实现AOP
2009-06-06 17:21 1544上面我们是使用注解的方式实现spring AOP的,下面 ... -
第18讲 --使用Spring的注解方式实现AOP的细节
2009-06-06 15:48 1562上一讲我们使用spring注解的方式理由aop技术 ... -
第17讲 --使用Spring的注解方式实现AOP入门
2009-06-05 00:48 2273使用Spring进行面向切面(AOP)编程 要 ... -
第16讲 --使用CGLIB实现AOP功能与AOP概念解释
2009-06-04 07:42 1636当代理对象没有实现 ... -
第15讲 --使用JDK中的Proxy技术实现AOP功能
2009-06-04 07:34 2333当目标类实现了接口,我们可以使用jdk的Proxy ... -
第14讲 --让Spring自动扫描和管理Bean
2009-06-02 23:40 8753通过在classpath自动扫描方式把组件纳入sp ... -
第13讲 --Autowire注解与自动装配
2009-06-02 22:46 31281. Autowire 默认是 ... -
第11讲 --用@Resource注解完成属性装配
2009-05-31 22:42 7039bean的注入方式有3种: 第一种:使用构造器注 ...
相关推荐
#### 二、UTF-16编码原理 UTF-16将Unicode字符集中的每一个字符映射到一个16位或32位的数值上。对于基本多文种平面(Basic Multilingual Plane,BMP)内的字符,UTF-16使用16位编码单元进行编码;而对于BMP之外的...
在Spring框架中,注解是实现依赖注入(Dependency Injection,DI)和简化配置的主要手段。在"Spring全注解Examples"这个项目中,我们将探讨如何使用Spring 4.2.2版本的注解来配置bean,执行AOP(面向切面编程)以及...
#### 第二部分:@Pointcut注解详解 1. **@Pointcut注解使用** - **方法级别**:@Pointcut注解通常用于定义具体的切点表达式。例如,可以通过`@Pointcut("execution(* com.example.demo.service.*.*(..))")`定义一...
"卷积编码与解码的MATLAB实现及性能分析" 本资源摘要信息是关于卷积编码与解码的MATLAB实现及性能分析的课程设计报告。下面是相关的知识点: 1、卷积编码的基本概念:卷积编码是一种通用的-channel coding技术,...
在这个例子中,`Employee`类代表了一个Excel工作表,其中`name`字段对应于第一行第一列,`age`字段对应于第一行第二列。 在实际应用中,我们还可以利用注解来定义更复杂的逻辑,如数据验证、样式设置、公式计算等。...
在“LTE系统中Reed-Muller码的编码研究与实现”这篇毕业设计中,作者可能详细介绍了Reed-Muller码的理论背景,分析了其在LTE环境下的性能优势,并给出了具体的软件或硬件实现方案。可能还包含了对不同级别Reed-...
74LS148是一款常见的集成电路,它实现了一个8输入、3输出的优先编码器功能。在这个设计中,我们将深入探讨74LS148的工作原理、8-3优先编码器的功能,以及如何在Proteus软件中进行电路仿真。 74LS148是TTL系列芯片,...
《MPEG-2压缩编码技术原理应用》是关于视频压缩编码领域的深度解析,主要探讨了MPEG-2标准的核心技术和实际应用。MPEG-2,全称Moving Picture Experts Group-2,是由国际电信联盟(ITU)和国际标准化组织(ISO)共同...
### LZW编码分析及其实现原理 #### 缘起与背景 LZW(Lempel-Ziv-Welch)作为一种高效的无损数据压缩算法,在多种应用场景中发挥了重要作用,包括Unix系统工具、GIF图像格式、TIFF文件格式等。该算法是对1978年由...
- **@Resource**:与@Autowired类似,但更加灵活。 - **@PostConstruct/@PreDestroy**:用于指定初始化方法和销毁方法。 ##### 3.2 基于注解的依赖注入 - **@Autowired**:自动装配Bean。 - 支持按类型装配、按...
标题“COPAl ELECTRONICS—SA-7000旋转编码开关(英文)”和描述“COPAl ELECTRONICS—SA-7000旋转编码开关(英文)pdf, COPAl ELECTRONICS—SA-7000旋转编码开关(英文)”暗示我们要讨论的是COPAl公司生产的SA-...
这个文件名表明它是一个关于G711编码的PowerPoint演示文稿,版本号为v2,日期为2007年3月5日,可能包含了详细的讲解和示例,帮助读者深入理解μ-law和A-law编码的原理以及它们在网络语音通信中的应用。 总的来说,G...
本文将详尽解读“三菱PLC程序源码-电子开料锯程序附注解.zip”中的内容,带领读者深入理解PLC编程原理,并结合电子开料锯的具体应用,探讨实际工程中的编程技巧。 一、PLC基础与三菱PLC概述 PLC是一种专为工业环境...
实现自定义注解的第一步是定义注解类。例如: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface BindView { int value(); } ``` 这里,`@Retention(RetentionPolicy....
Spring Boot源码解析是深入了解Spring Boot内部工作原理和机制的重要途径。通过源码分析,开发者可以更好地理解Spring Boot的自动装配、启动流程以及如何自定义启动器。Spring Boot的自动装配原理涉及到Spring Boot...
综上所述,P1-P4相位编码信号的生成与分析是一个涉及信号处理、编码理论和雷达原理的综合性课题。在MATLAB环境下,通过编写和运行代码,不仅可以理解相位编码的原理,还能直观地观察到各种编码信号的特性,为雷达...
哈夫曼编码是一种高效的数据压缩方法,主要用于无损数据压缩,尤其在文本、图像和音频文件的压缩中广泛应用。在数据结构课程设计中,哈夫曼编码是一个经典的实践项目,它涉及到了二叉树、优先队列(最小堆)以及编码...
编译原理实验2-LL(1)分析法实现 编译原理实验2 LL(1)分析法是编译原理的一种重要分析方法,用于分析和预测分析表的构建。该实验的主要目标是实现 LL(1)分析法,并使用预测分析表来分析输入的语句。 知识点1...
此外,`@Resource`注解也可以用于字段或setter方法的注入,主要用于JSR-250规范的支持。 六、最佳实践 1. 避免过多的自动注入,尽量明确依赖关系,使用构造器注入优先。 2. 使用`@Qualifier`或`@Resource`注解提高...
2. **字符串转换函数**:在C++中,可以使用标准库中的`std::wstring_convert`或第三方库(如iconv、ICU)提供的函数来实现编码间的转换。例如,从GBK到UTF-8的转换,可以先将GBK编码的宽字符串转换为字节流,然后再...