1、定义注解(用于标准那些字段需要注入值)
package com.carry.reflect.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
* @Target
* 1.CONSTRUCTOR:用于描述构造器
* 2.FIELD:用于描述字段
* 3.LOCAL_VARIABLE:用于描述局部变量
* 4.METHOD:用于描述方法
* 5.PACKAGE:用于描述包
* 6.PARAMETER:用于描述方法参数
* 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
* @Retention
* 1.SOURCE:在源文件中有效(即源文件保留)
* 2.CLASS:在class文件中有效(即class保留)
* 3.RUNTIME:在运行时有效(即运行时保留)
*
* 该注解用于标记哪些字段应该被自动注入
*/
@Target({FIELD})
@Retention(RUNTIME)
public @interface Inject {
String name() default "";
}
2、定义控制器
package com.carry.reflect.controller;
import com.carry.reflect.annotation.Inject;
import com.carry.reflect.entity.User;
import com.carry.reflect.service.UserService;
public class UserController {
@Inject(name="com.carry.reflect.service.impl.UserServiceImpl")
private UserService userService;
public void saveUser(User user) {
System.out.println("控制器处理开始!!!");
userService.saveUser(user);
System.out.println("控制器处理结束!!!");
}
}
3、定义service接口
package com.carry.reflect.service;
import com.carry.reflect.entity.User;
public interface UserService {
void saveUser(User user);
}
4、定义service实现
package com.carry.reflect.service.impl;
import com.carry.reflect.annotation.Inject;
import com.carry.reflect.dao.UserDao;
import com.carry.reflect.entity.User;
import com.carry.reflect.service.UserService;
public class UserServiceImpl implements UserService {
@Inject(name="com.carry.reflect.dao.impl.UserDaoImpl")
private UserDao userDao;
public void saveUser(User user) {
System.out.println("service处理开始!!!");
userDao.saveUser(user);
System.out.println("service处理结束!!!");
}
}
5、定义DAO接口
package com.carry.reflect.dao;
import com.carry.reflect.entity.User;
public interface UserDao {
void saveUser(User user);
}
6、定义DAO实现
package com.carry.reflect.dao.impl;
import com.carry.reflect.dao.UserDao;
import com.carry.reflect.entity.User;
public class UserDaoImpl implements UserDao {
public void saveUser(User user) {
System.out.println(user+"保存成功!!!");
}
}
7、定义测试类(此类包含注入的方法)
package com.carry.reflect.demo;
import java.lang.reflect.Field;
import org.junit.Test;
import com.carry.reflect.annotation.Inject;
import com.carry.reflect.controller.UserController;
import com.carry.reflect.entity.User;
public class UserTest {
@Test
public void testSaveUser() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> classs = registerClassName("com.carry.reflect.controller.UserController");
UserController userController = (UserController) classs.newInstance();
setObject(classs,userController);
User user = new User("zhangsan","123456",18);
userController.saveUser(user);
}
/**
* 给目标上所有加了@Inject注解的字段注入值
* @param classs 该值跟target类一致
* @param target 需要注入属性的对象
* @throws ClassNotFoundException
*/
public void setObject(Class<?> classs,Object target) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//获取该类里所有的属性(包括私有的属性)
Field[] fields = classs.getDeclaredFields();
for(Field field : fields) {
//通过字段类型创建对象
//判断字段是否存在@Inject,如果存在则注入
Inject inject = field.getAnnotation(Inject.class);
if(inject != null) {
String className = inject.name();
Object fieldObj = registerClassName(className).newInstance();
//压制权限访问检查
field.setAccessible(true);
//注入对象
field.set(target, fieldObj);
//递归调用,把所有与UserController直接的和间接的对象依次注入
setObject(registerClassName(className),fieldObj);
}
}
}
/**
* 通过类名去注册
* @param className 类名
* @return
*/
private Class<?> registerClassName(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> classs = null;
if(className != null) {
classs = Class.forName(className);
}
return classs;
}
}