IoC和DI
IoC - Inversion of Control
是技术思想,不是技术实现,描述java开发领域对象的创建和管理的问题。
传统开发方式:依赖某个对象时,new一个该对象。
IoC思想开发方式:不自己new对象,将创建和管理对象的权利交给IoC对象,需要使用某个对象的时候,问IoC容器要。
为什么叫控制反转?
- 控制:对象的创建(实例化)的权利。
- 反转:控制权交给外部环境(spring框架 / IoC容器)。
IoC vs DI
描述的是同一件事情,但是角度不一样。
IoC是站在对象的角度,对象实例化及其管理的权利交给(反转给)了容器。
DI是站在容器的角度,容器会把对象依赖的其他对象注入(送进去),如A对象实例化过程中因为声明了一个B类型的属性,那么就需要容器把B对象注入给A。
AOP
Aspect Oriented Programming,面向切面编程。
OOP思想是垂直纵向的继承体系,可以解决大多代码重复问题,但不是全部,需要AOP思想。
在多个纵向(顺序)流程中出现的相同子流程代码,我们称之为横切逻辑代码。
使用场景:
- 事务控制
- 权限校验
- 日志
AOP踢出横向抽取机制,将横切逻辑代码与业务逻辑代码分离。
不改变业务逻辑的情况下,把横切逻辑代码应用到原有的业务逻辑中,达到和原来一样的效果。
- 切:横切逻辑,原有业务逻辑代码不动,只操作横切逻辑代码。
- 面:横切逻辑代码影响多个方法,多个点构成面。
实现IoC和AOP
除了new以外,还有什么技术可以实例化对象?
使用反射:Class.forName("全限定类名");
可以把全限定类名配置在xml中。
利用反射技术,配合工厂模式生产对象。工厂模式是一种非常好的解耦合的方式。
因此最终方案为,实现一个工厂类,它能够:
- 读取解析xml,然后通过反射技术实例化对象;
- 给外部提供获取对象的接口方法。
**
数据库事务归根结底是Connection的事务:
提交事务:connection.commit();
回滚事务:connection.rollback();
贴一个ProxyFactory源码:
package com.lagou.edu.factory;import com.lagou.edu.utils.TransactionManager;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import java.lang.reflect.Proxy;/*** @author 应癫*** 代理对象工厂:生成代理对象的*/public class ProxyFactory {private TransactionManager transactionManager;public void setTransactionManager(TransactionManager transactionManager) {this.transactionManager = transactionManager;}/*** Jdk动态代理** @param obj 委托对象* @return 代理对象*/public Object getJdkProxy(Object obj) {// 获取代理对象return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),(proxy, method, args) -> {Object result;try {// 开启事务(关闭事务的自动提交)transactionManager.beginTransaction();result = method.invoke(obj, args);// 提交事务transactionManager.commit();} catch (Exception e) {e.printStackTrace();// 回滚事务transactionManager.rollback();// 抛出异常便于上层servlet捕获throw e;}return result;});}/*** 使用cglib动态代理生成代理对象** @param obj 委托对象* @return*/public Object getCglibProxy(Object obj) {return Enhancer.create(obj.getClass(), (MethodInterceptor) (o, method, objects, methodProxy) -> {Object result;try {// 开启事务(关闭事务的自动提交)transactionManager.beginTransaction();result = method.invoke(obj, objects);// 提交事务transactionManager.commit();} catch (Exception e) {e.printStackTrace();// 回滚事务transactionManager.rollback();// 抛出异常便于上层servlet捕获throw e;}return result;});}}
