依赖注入是Spring中一个极其重要的概念。
本文通过JDK的注解和反射机制来完成在Spring中完成依赖注入的功能。
预备知识,注解,反射机制
完成一个注解我们通常需要三个步骤1,定义注解,2,使用注解,3,解析注解
下面我们通过实例来解释注解的使用
定义注解
package cn.tang.demos.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD) //注解用在什么地方,method,field,class,type
@Retention(RetentionPolicy.RUNTIME)//注解用在什么级别,Source,class,runtime
public @interface Autoware {
String description() default "类似spring的自动装载";//注解元素的默认值
}
使用注解
package cn.tang.demos.spring;
public class Bean {
@Autoware(description="数据访问接口")
private MysqlDao dao;
public void testAdd(){
dao.add();
}
public MysqlDao getDao() {
return dao;
}
public void setDao(MysqlDao dao) {
this.dao = dao;
}
}
解析注解,下面代码包括了依赖注入的内容
package cn.tang.demos.spring;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class DITest {
/**
* 依赖注入的测试类,假设已经从xml配置文件中读取出来了两个Bean的类名
*/
private static final String daoClassStr = "cn.tang.demos.spring.MysqlDao";
private static final String beanClassStr = "cn.tang.demos.spring.Bean";
public static void main(String[] args) {
try {
test();// 为了能让代码更加直观,没有分别处理所有类型的异常,也没有多余的判断
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public static void test() throws Exception {
// 根据类名得到类类型
Class daoClass = Class.forName(daoClassStr);
// 根据类得到该类的构造方法
Constructor daoCon = daoClass.getDeclaredConstructors()[0];
// 调用构造方法得到类的一个实例
MysqlDao dao = (MysqlDao) daoCon.newInstance();
// 根据类名得到类类型
Class beanClass = Class.forName(beanClassStr);
// 根据类得到该类的构造方法
Constructor beanCon = beanClass.getDeclaredConstructors()[0];
// 调用构造方法得到类的一个实例
Object beanObject = beanCon.newInstance();
// 遍历所有的属性
for (Field f : beanClass.getDeclaredFields()) {
// 获取有注入类型的注解
Autoware an = (Autoware) f.getAnnotation(Autoware.class);
// 根据属性得到声明属性的类型 f.getGenericType()
if (an != null) {
// 输出注解的描述内容
System.out.println("annotation description : "
+ an.description());
// 得到与该属性的set方法,这也是为什么spring中的属性需要set方法
String setMethodName = "set"
+ f.getName().substring(0, 1).toUpperCase()
+ f.getName().substring(1);
//得到该方法
Method m = beanClass.getDeclaredMethod(setMethodName,
new Class[] { (Class) f.getGenericType() });
if (m != null) {
//反射机制调用该方法,注入DAO到bean中
m.invoke(beanObject, dao);
}
}
}
//现在我们得到了一个注入了dao的bean了,我们调用bean中的方法
((Bean) beanObject).testAdd();
}
}
分享到:
相关推荐
javaweb开发,spring,springMVC所有依赖包对应jdk1.8版本
熟练使用spring和jdk的注解类,优质视频教程,学完后受益良多
该jar包兼容了jdk1.3到1.8,可以放心使用。
spring3.2.0与jdk1.8冲突
使用jdk1.6 注解开发web服务,注解分析
低版本spring兼容高版本jdk,原有项目升级jdk和tomcat
解决“annotation-config are only available on JDK 1.5 and higher”的问题!
给了jdk1.7和spring3搭配的jar包,和jdk1.8和spring4搭配的jar包。原因如下:jdk1.7和spring3的jar包兼容。jdk1.8及以上和spring3的jar包不兼容!jdk1.8及以上和spring4的jar包兼容。非常靠谱!!!并且已经踩过jar...
jdk和spring,平常开发用到的技术
JDK 8 + Spring Boot 2.7.18
史上最全Java开发文档,包括JDK,Spring,JQuery,JS等
如果是jdk7就直接用4.2.0 jdk8的话用5.0就可以了 ok
SpringCloud+JDK17整合EaseExcel
Struts2.3.28+spring4.1.6+hibernate4.3.8整合总结(注解),测试环境使用myeclipse2014,jdk1.6
jdk8下注解的应用例子,详细的举例了使用方法,大家可以间接参考
spring aop jdk 动态代理的底层实现解析模拟
jdk_spring_api
lamp-cloud 基于Jdk11 + SpringCloud + SpringBoot 开发的微服务中后台快速开发平台,专注于多租户(SaaS架构)解决方案,亦可作为普通项目(非SaaS架构)的基础开发框架使用,目前已实现插拔式数据库隔离、SCHEMA隔离...
一个全面使用JDK1.8语法的J2EE示例,附带模拟数据库操作和基于注解的Bean注入管理。供J2EE开发新手学习。无需spring,掌握SpringMvc主要的开发思路。
org.springframework.core.JdkVersion 于是找到一个spring-core-3.x.RELEASE.jar,用其中的JdkVersion这个类替换spring-2.5.5.jar对应class,问题解决! 注意:别用spring-core-4.x.RELEASE.jar,JdkVersion....