SpringIOC 小案例学习
由于毕业前夕无聊,所以就索性把基础的东西都过一遍
1. 注解
用到的注解有 @Bean 和 @AutoWried
相信用过Spring框架的同学来说这并不陌生
Bean.java
package com.guet.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 2358189586
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {
}
AutoWried.java
package com.guet.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 2358189586
*/
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoWired {
}
2. Dao层
为了遵循企业的开发规则,用接口和实现类来进行解耦
IUserDao。java
package com.guet.dao;
import com.guet.entity.User;
/**
* @author 2358189586
*/
public interface IUserDao {
/**
* 通过id获取User
*
* @param id
* @return
*/
User getUserById(String id);
}
UserDaoImpl.java
package com.guet.dao.impl;
import com.guet.annotation.Bean;
import com.guet.dao.IUserDao;
import com.guet.entity.User;
/**
* @author 2358189586
*/
@Bean
public class UserDaoImpl implements IUserDao {
//模拟数据库查询
@Override
public User getUserById(String id) {
User user = new User();
user.setId("7788");
user.setAge(18);
user.setUserName("xl");
user.setPassWord("123456");
return user;
}
}
3.Service层
IUserService.java
package com.guet.service;
/**
* @author 2358189586
*/
public interface IUserService {
/**
* 登陆
*/
void login();
}
UserServiceImpl.java
package com.guet.service.impl;
import com.guet.annotation.AutoWired;
import com.guet.annotation.Bean;
import com.guet.dao.IUserDao;
import com.guet.dao.impl.UserDaoImpl;
import com.guet.entity.User;
import com.guet.service.IUserService;
/**
* @author 2358189586
*/
@Bean
public class UserServiceImpl implements IUserService {
@AutoWired
private IUserDao userDao;
@Override
public void login() {
User userById = userDao.getUserById("7788");
System.out.println(userById);
System.out.println("这是登陆方法");
}
}
模拟Spring启动
main.java
import com.guet.reflect.ApplicationContext;
import com.guet.service.IUserService;
import com.guet.service.impl.UserServiceImpl;
/**
* @author 2358189586
*/
public class Main {
public static void main(String[] args) {
// write your code here
ApplicationContext applicationContext = new ApplicationContext();
//从out编译的包中扫描带@Bean的类,并通过全类名反射实例化放入beanFactory的Map中
applicationContext.load();
// beanFactory里的实例化拿到该类的Filed字段并判断是否有@AutoWried,并强赋值
applicationContext.assembleObject();
//测试是否成功
UserServiceImpl bean = (UserServiceImpl)applicationContext.getBean(IUserService.class);
bean.login();
}
}
ApplicationContext.java
private HashMap<Class, Object> beanFactory = new HashMap<>();
private String filePath;
public T getBean(Class clazz) {
return (T) beanFactory.get(clazz);
}
public void load() {
filePath = ApplicationContext.class.getClassLoader().getResource("").getFile();
System.out.println(filePath);
loadOne(new File(filePath));
}
/**
* 加载一个文件夹的类
*
* @param fileParent
*/
private void loadOne(File fileParent) {
if (fileParent.isDirectory()) {
File[] childrenFiles = fileParent.listFiles();
if (childrenFiles == null || childrenFiles.length == 0) {
return;
}
for (File child : childrenFiles) {
if (child.isDirectory()) {
//如果是个文件夹就继续调用该方法,使用了递归
loadOne(child);
} else {
//通过文件路径转变成全类名,第一步把绝对路径部分去掉
// D:\mytools
// com\xinzhi\dao\UserDao.class
String pathWithClass = child.getAbsolutePath().substring(filePath.length() - 1);
//选中class文件
if (pathWithClass.contains(".class")) {
// com.xinzhi.dao.UserDao
//去掉.class后缀,并且把 \ 替换成 .
String fullName = pathWithClass.replaceAll("\\\\", ".").replace(".class", "");
try {
Class<?> aClass = Class.forName(fullName);
//把非接口的类实例化放在map中
if (!aClass.isInterface()) {
Bean annotation = aClass.getAnnotation(Bean.class);
if (annotation != null) {
Object instance = aClass.newInstance();
//判断一下有没有接口
if (aClass.getInterfaces().length > 0) {
//如果有接口把接口的class当成key,实例对象当成value
System.out.println("正在加载【" + aClass.getInterfaces()[0] + "】,实例对象是:" + instance.getClass().getName());
beanFactory.put(aClass.getInterfaces()[0], instance);
} else {
//如果有接口把自己的class当成key,实例对象当成value
System.out.println("正在加载【" + aClass.getName() + "】,实例对象是:" + instance.getClass().getName());
beanFactory.put(aClass, instance);
}
}
}
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 给带有@AutoWried所有的字符赋值
*/
public void assembleObject() {
for (Map.Entry<Class, Object> entry : beanFactory.entrySet()) {
//就是咱们放在容器的对象
Object obj = entry.getValue();
Class<?> aClass = obj.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields) {
AutoWired annotation = field.getAnnotation(AutoWired.class);
if (annotation != null) {
field.setAccessible(true);
try {
System.out.println("正在给【" + obj.getClass().getName() + "】属性【" + field.getName() + "】注入值【" + beanFactory.get(field.getType()).getClass().getName() + "】");
field.set(obj, beanFactory.get(field.getType()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
运行结果
/D:/Intllij/projects/resourceCode/out/production/resourceCode/
正在加载【interface com.guet.dao.IUserDao】,实例对象是:com.guet.dao.impl.UserDaoImpl
正在加载【interface com.guet.service.IUserService】,实例对象是:com.guet.service.impl.UserServiceImpl
正在给【com.guet.service.impl.UserServiceImpl】属性【userDao】注入值【com.guet.dao.impl.UserDaoImpl】
User{id='7788', userName='xl', passWord='123456', age=18}
这是登陆方法