Java通过反射注入

 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;
	}
}

 

转载于:https://my.oschina.net/u/3288608/blog/888685

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值