基于之前的添加pom文件
<!--反射工具包-->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
<!--工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
配置文件
basePackage=com.liu
注解
/**
* @Description 用于注入一个对象
* @ClassName Autowired 类名
* @Author 刘楠
* @date 2020.06.30
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* 依赖必须存在,不然就报错
* @return
*/
boolean required() default true; //true就必须注入
}
/**
* @Description 用于标记一个类
* @ClassName Service 类名
* @Author 刘楠
* @date 2020.06.30
*/
@Documented
@Target(ElementType.TYPE) //只能用在类上
@Retention(RetentionPolicy.RUNTIME)
public @interface Service {
/**
* 类的id名称
* @return
*/
String value() default "";//可以有也可以没有
}
@Target({ElementType.TYPE}) //类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Transactional {
/**
* 这个给个默认值也可以给空,工厂里获取也可以 这个省个事
* @return
*/
String value() default "transactionManager"; //默认事务管理器
}
在dao service TransactionManager ProxyFactory修改使用以上注解
- dao
@Service("accountDao")
public class JdbcAccountDaoImpl implements AccountDao {
@Autowired
private ConnectionUtils connectionUtils;
- service
@Service("transferService")
@Transactional
public class TransferServiceImpl implements TransferService {
// 最佳状态
@Autowired
private AccountDao accountDao;
- TransactionManager
@Service("transactionManager")
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils;
- ProxyFactory
@Service("proxyFactory")
public class ProxyFactory {
@Autowired
private TransactionManager transactionManager;
public void setTransactionManager(TransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
新增一个工具类
public class PropertiesUtils {
private static Properties props = new Properties();
public static Properties getProperties(String path) {
InputStream in = PropertiesUtils.class.getClassLoader().getResourceAsStream(path);
try {
props.load(in);
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
}
修改 BeanFactory原来改名BeanFactoryOld不用,新建BeanFactory
public class BeanFactory {
private static Map<String, Object> map = new ConcurrentHashMap<>(); // 存储对象
//默认要扫描的包,可通过配置文件来 如果配置文件中为空就使用这个
private static String basePackage = "com.liu";
private static String basePackageKey = "basePackage";
static {
try {
/**
* 1.扫描指定包下的所有类,获取指定注解的类的集合
* 2.使用反射创建对象
* 3.获取Service注射标记的类
* 4.判断注解value是否有值,有就放入容器
* 5.无值 如果有是类就获取类名称,并放入容器
* 6.无值情况下获取接口的名称,如果无值同时接口数量大于1就抛出异常
* 7.无值只有一个接口,获取接口名称放入容器
* 8.初始化完成
*/
doInitializationBean();
/**
* 判断是否有Autowired,
*/
doAutowired();
/**
* Transactional注解标记的类
*/
doTransactional();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 初始化Bean,并放入容器中
* @throws InstantiationException
* @throws IllegalAccessException
*/
private static void doInitializationBean() throws InstantiationException, IllegalAccessException {
//1.加载配置因为文件
Properties properties = PropertiesUtils.getProperties("base.properties");
String property = properties.getProperty(basePackageKey);
//如果配置文件中没有,就用默认的
if (StringUtils.isBlank(property)) {
property = basePackage;
}
//2.使用反射工具类获取所有带Service注解的类
Reflections reflections = new Reflections(property);
//获取所有Service注解的类
Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(Service.class);
//3. 通过反射实实例化
for (Class<?> clazz : classSet) {
//实例化通过无参数构造
Object newInstance = clazz.newInstance();
//获取注解
Service annotation = clazz.getAnnotation(Service.class);
//获取注解中的值
if(StringUtils.isBlank(annotation.value())) { //注解没有值
//获取接口类
Class<?>[] interfaces = clazz.getInterfaces();
if (interfaces.length > 1) { //判断接口数量是否>1
throw new RuntimeException("该有多个父接口,并没有指定名称,请使用Service注解指定名称");
}
if (interfaces.length == 0) { //接口数量为0,没有接口
//没有接口就是个类获取类名称
String simpleName = clazz.getSimpleName();
//首字母小写
String key = StringUtils.uncapitalize(simpleName);
//放入容器中
map.put(key,newInstance);
} else {
//接口数量为1
//接口名称
String simpleName = interfaces[0].getSimpleName();
//首字母小写
String key = StringUtils.uncapitalize(simpleName);
//放入容器中
map.put(key,newInstance);
}
}else {
//注解中有值
//4.将类放入容器中
String id = annotation.value();
//首字母小写
String key = StringUtils.uncapitalize(id);
//放入容器中
map.put(key,newInstance);
}
}
}
/**
* 注入
*/
private static void doAutowired() {
try {
//从容器中获取循环判断
for(Map.Entry<String,Object> entry:map.entrySet()){
//1.获取创建的对象
String objKey = entry.getKey();
Object value = entry.getValue();
//2.获取对象的类
Class clazz =value.getClass();
//获取所有属性字段
Field[] fields = clazz.getDeclaredFields();
//循环处理
for (Field field : fields) {
//3.判断是否有Autowired注解
if(field.isAnnotationPresent(Autowired.class)&& field.getAnnotation(Autowired.class).required()){
//4.如果是有Autowired并且值是true,就从容器中去获取对象
String simpleName = field.getType().getSimpleName();
//5.将首字母小写
String key = StringUtils.uncapitalize(simpleName);
//获取要注入的对象
Object o = map.get(key);
//没有就异常
if(o==null){
throw new RuntimeException(simpleName+"依赖的对象不存在 是null");
}
//获取这个类的方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
//6.找到对应字段set方法
if(method.getName().equalsIgnoreCase("set"+simpleName)){
//7.执行setter方法赋值
method.invoke(value, o);
}
}
}
}
/**
* 为什么不在这里做事务,因为事务代理工厂,也需要注入,可能没有完成初始完成,放在下一轮中都实例和注入完成后,再代理
* public class ProxyFactory {
*
* @Autowired
* private TransactionManager transactionManager;
*/
//8.重新放入容器中
map.put(objKey, value);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* 事务代理
*/
private static void doTransactional() {
for(Map.Entry<String,Object> entry:map.entrySet()) {
//1.获取创建的对象
String key = entry.getKey();
Object value = entry.getValue();
//2.获取属性
Class clazz = value.getClass();
//3.判断当前对象的类是否有Transactional
if(clazz.isAnnotationPresent(Transactional.class)){
//4.有这个注解说明要开启事务,获取代理工厂
ProxyFactory proxyFactory = BeanFactory.getBean("proxyFactory", ProxyFactory.class);
//5.判断 这个对像是否有实现接口
Object proxyObj=null;
Class[] interfaces = clazz.getInterfaces();
//判断有没有接口
if(interfaces!=null&&interfaces.length>0){
//6.有接口使用jdk
proxyObj = proxyFactory.getJdkProxy(value);
}else{
//7.就是个类使用cglib
proxyObj = proxyFactory.getCglibProxy(value);
}
//8.重新放入容器中 将代理对象放入
map.put(key, proxyObj);
//10.完成代理
}
}
}
public static Object getBean(String id) {
return map.get(id);
}
public static <T> T getBean(String id,Class<T> clazz) {
return (T)map.get(id);
}
}
修改servlet
public class TransferServlet extends HttpServlet {
/**
* 通过工厂获取Service
*/
private TransferService transferService = BeanFactory.getBean("transferService",TransferService.class) ;
修改完成