自动new对象
public class SelfMotion<T> {
//首先建两个注解,一个放在类上,一个放在字段上
//建一个容器,用map存,方便new对象
private HashMap<Class,Object> beanFactory = new HashMap<>();
//根目录
private String filePath;
public T getBean(Class clazz){
return (T)beanFactory.get(clazz);
}
//自动new对象
public void initContextByAnnotation() {
//拿到out下的工程目录
filePath = SelfMotion.class.getClassLoader().getResource("").getFile();
//load过滤
load(new File(filePath));
assembleObject();
}
//当工程目录传进来后,扫描它的所有子目录
public void load(File fileParent) {
//先判断,如果是一个文件夹
if (fileParent.isDirectory()) {
//拿到文件夹下的所有文件
File[] files = fileParent.listFiles();
//如果没有文件,就结束方法
if (files.length == 0 || files == null) {
return;
}
//如果有文件,遍历
for (File file : files) {
if (file.isDirectory()) {
//判断是否为文件夹,就调用自身
load(file);
} else {
//不是文件的话就把文件路径转换为全类名
//返回绝对路径
String substring = file.getAbsolutePath().substring(filePath.length() - 1);
if (substring.contains(".class")) {
//如果是.class文件,去掉class,把\替换成.,四个\代表一个\
String replace = substring.replaceAll("\\\\", ".")
.replace(".class", "");
//拿到了类的全路径,例如com.xinzhi.annotation.AutoWrite,然后就要实例化对象
try {
//反射拿到class
Class<?> aClass = Class.forName(replace);
//判断是否为接口
if (!aClass.isInterface()) {
Bean annotation = aClass.getAnnotation(Bean.class);
//判断有没有Bean注释,Bean专属于类
if (annotation != null) {
//不是接口,且有Bean,new
Object instance = aClass.newInstance();
if (aClass.getInterfaces().length > 0) {
//如果有接口,接口的class就是key,实例对象是value
//存在map里
beanFactory.put(aClass.getInterfaces()[0], instance);
} else {
//否则,自己的class就是key,实例对象是value
beanFactory.put(aClass, instance);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
//这样new出来的对象是空的,没有任何属性
//为字段配置属性
private void assembleObject() {
//遍历map
for (Map.Entry<Class, Object> entry : beanFactory.entrySet()) {
//拿到每一个对象
Object value = entry.getValue();
//拿到class
Class<?> aClass = value.getClass();
//拿到所有字段
Field[] declaredFields = aClass.getDeclaredFields();
//遍历判断如果有AutoWrite注解就注入
for (Field field : declaredFields) {
AutoWrite annotation = field.getAnnotation(AutoWrite.class);
if (annotation != null) {
field.setAccessible(true);
try {
//为遍历的每个字段赋值,值就是类对象
field.set(value, beanFactory.get(field.getType()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
@Bean
public class UserService {
private SelfMotion selfMotion = new SelfMotion();
@AutoWrite
private UserDao userDao;
public User login() {
selfMotion.initContextByAnnotation();
IUserDao userDao = (IUserDao) selfMotion.getBean(IUserDao.class);
}
}
baseDao
//类名字段名要与数据库表完全一致
public class BaseDao<T> {
public List<T> findAll(Class<T> clazz) {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<T> list = new ArrayList<>();
//先拼一个sql语句 select 列名 from 表名
try {
//放拼接下的SQL语句
StringBuilder sql = new StringBuilder();
sql.append("select ");
//拿到传进来类对象的所有字段
Field[] fields = clazz.getDeclaredFields();
//遍历每一个字段的名字,转为小写,加上,号
for (Field field : fields) {
sql.append(field.getName().toLowerCase()).append(",");
}
//,号是每次遍历都会加的,要删除最后一个字符,也就是,号
sql.deleteCharAt(sql.length() - 1);
sql.append(" from ");
//全类名com.xinzhi.entity.user,只要user
String str = clazz.getName().toLowerCase();
//最后一个.前面有多少位
int i = User.class.getName().lastIndexOf(".");
//截串
String substring = str.substring((i + 1));
sql.append(substring);
//拿到连接执行SQL语句
Connection connection = getConnection();
preparedStatement = connection.prepareStatement(sql.toString());
resultSet = preparedStatement.executeQuery();
//遍历
while(resultSet.next()){
//反射new实例
Object obj = clazz.newInstance();
for (Field field : fields) {
//字段名就是列名
Object value = resultSet.getObject(field.getName());
//私有字段暴力注入
field.setAccessible(true);
//为实例对象赋值
field.set(obj,value);
}
list.add((T)obj);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
close(preparedStatement,resultSet);
}
return list;
}
版权声明:本文为weixin_46177455原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。