反射实现 BasicDao之后无法封装出来,好像必须依赖注解,在线等

package cn.peng.dao;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;

import cn.itcast.jdbc.TxQueryRunner;

/**
 * 根据反射泛型以及反射Class 实现BasicDao小工具
 * 实现增删改查操作 继承此类,只用传递对应类名
 * 且在该类中设置注解,注解的值就是数据库的列名以及表名
 *  调用此类add/delete/modify/select方法即可完成对数据库操作
 * @author peng'peng
 * @param <T>
 */
public class BasicDao<T> {
	private QueryRunner qr = new TxQueryRunner();
	private Class<T> beanClass;
	public BasicDao() {
		//得到传递过来的泛型类的class名称
//		Type c = this.getClass().getGenericSuperclass();
//		ParameterizedType ptype = (ParameterizedType) c;
//		Class beanClass = (ptype.getActualTypeArguments())[0].getClass();
//		System.out.println("beanClass:"+beanClass.getName());
		Class beanClass = (Class)((ParameterizedType)this.getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
		this.beanClass = beanClass;
		System.out.println(beanClass.getName());
	}
	
	public void add(T t) throws SQLException, IllegalArgumentException, IllegalAccessException {
		/**
		 * 使用反射得到该T的表名,以及各个列名
		 */
		//使用反射得到类的注解名称的值 --》得到表名
		//得到表名
		//TableName tableNameAnno = (TableName)beanClass.getAnnotation(TableName.class);
		//String table = tableNameAnno.value();
		TableName table = t.getClass().getAnnotation(TableName.class);
		String tableName = table.value();
		System.out.println(t.getClass().getName());
		System.out.println(tableName);
		//使用map集合 存储每个列名对应的值
		Map<String,String> map =  new LinkedHashMap<String, String>();
		//得到表名注解的成员变量的集合 //此处只能使用DeclaredFields方法 得到本类,Field是得到父类的共有字段
		Field[] fields = t.getClass().getDeclaredFields();
		fields[0].setAccessible(true);//设置禁用访问权限
		ID id = (ID) fields[0].getAnnotation(ID.class);
		//得到表主键名称以及对应值
		map.put(id.value(), (String) fields[0].get(t));
		//字符串拼接
		StringBuilder sb = new StringBuilder();
		for(int i=1;i<fields.length;i++) {
			//将列名以及对应的值存到map中
			fields[i].setAccessible(true);//先设置禁用每个属性的访问权限
			String value = fields[i].getAnnotation(Column.class).value();
			map.put(value,  fields[i].get(t)+"");
			if(i-1<fields.length-1) {
				sb.append("?,");
			}else {
				sb.append("?");
			}
		}
		sb.append("?");//补上最后一个参数?
		String sql ="insert into "+tableName+" values("+sb.toString()+")";
		Object[] params = map.values().toArray();
		qr.update(sql, params);
	}
	
}

上面是我封装的BasicDao 初版,在同一包下测试成功,当我在其他包下的时候,报异常,说是 TableName 那里的值为null
下面是我的包结构:

我觉得可能问题出在注解那里,我对注解也是今天才学了一点,只知道使用getAnnotation(Class) 得到指定注解名对象
如果此项目有能帮到我的地方,万分感谢!!!

这是测试类Book的注解:


数据库的表是对的,这个测试成功了,就是在其他包下使用就报错
报错提示如下:


如果还有需要补充的 欢迎评论

@SpringBootTest
class TravelServerApplicationTests {
    private user u1=new user();
    @Autowired
    private user u2;
    @Autowired
    ApplicationContext applicationContext;
    @Test
    void contextLoads() throws IllegalAccessException, InstantiationException {
        Arrays.stream(user.class.getAnnotations()).forEach(System.out::println);
        System.out.println("-------------------");
        Arrays.stream(u1.getClass().getAnnotations()).forEach(System.out::println);
        System.out.println("-------------------");
        Arrays.stream(u2.getClass().getAnnotations()).forEach(System.out::println);
        user bean = applicationContext.getBean(user.class);
        System.out.println("-------------------");
        Arrays.stream(bean.getClass().getAnnotations()).forEach(System.out::println);
        user u3 = user.class.newInstance();
        System.out.println("-------------------");
        Arrays.stream(u3.getClass().getAnnotations()).forEach(System.out::println);
    }
}

spring管理的bean无法获取注解

因为这里的bean其实是一个代理类

AopUtils.getTargetClass(Obj)

可以使用这个方法获取

...看不懂,今天才开始学spring框架,我实现的时候,就是用原始的反射啥的实现的,没有使用框架,如果原始的方式能指点一下更好,不过也无伤大雅,毕竟以后都是使用框架了,还是先谢谢各位前辈哈