摘要:
本文简要介绍了Spring中两个重要的概念IOC控制反转和AOP面向切面编程,包括基本思想及其实现的基本原理,帮助小伙伴快速地了解IOC和AOP。
一,Spring IOC
IOC全称控制反转,代表一种创建和获取对象的技术思想,是 Spring 框架的核心思想之一。
控制:开发者手动控制对象的创建、依赖的组装。
public class UserService {
private UserDao userDao = new UserDao();
public void save() {
userDao.insert();
}
}
反转:对象的创建权、依赖管理权从开发者反转给了 Spring 容器。
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void save() {
userDao.insert();
}
}
以前Java中创建一个类对象通常需要我们手动地使用new关键字,而采用IoC控制反转技术后,我们可以省去大量的手动创建类对象的工作,类对象的创建由Spring容器帮我们完成,通过XML文件和注解的方式快速地生成类对象并储存在IoC容器中,也就是我们常说的 Bean(默认单例)
因此我们可以直接通过依赖注入的方式直接调用某个对象,这种简洁的方式让我们能够专注于业务上而不是这种重复的工作,同时也实现了代码的解耦
二,依赖注入
Spring容器在创建对象时,自动将其依赖的其他对象传递给它,无需开发者手动设置。
IOC是一种技术思想,而依赖注入就是实现IOC的具体技术手段。
常见的注入方式有3种:
1,构造器注入
@Service
public class UserService {
private UserDao userDao;
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
2,setter方法注入
@Service
public class UserService {
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
3,字段注入
@Service
public class UserService {
@Autowired
private UserDao userDao;
......
}
现在我们能够直接通过依赖注入的方式随心所欲地使用各个对象,但是如果A类中注入B,而B类中又注入A,这样形成一个依赖循环怎么办?
三,循环依赖
循环依赖指的是两个类的属性相互依赖,A类中有B对象属性,B类中又有A对象属性;
Spring通过三级缓存的方式能够解决单例模式下的Setter/Field注入的循环依赖,但是构造器注入必须在实例化前获得依赖进而无解。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new ConcurrentHashMap(16);
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
(1)一级缓存:singletonObjects的Map集合用于存储完整的Bean
(2)二级缓存:earlySingletonObjects二级缓存存放Bean的早期引用
(3)三级缓存:singletonFactories三级缓存存放Bean 实例化完成的 ObjectFactory 工厂对象

四,Spring AOP
AOP全称面向切面编程,我们知道Java是一门面向对象的语言,其实AOP所谓的切面本质就是对非业务代码逻辑的一种抽象,以减少系统的重复代码,降低模块间的耦合度。
注意:代理对象的类型是接口而不是对象本身:

常见场景:日志采集、事务控制、权限管理。
AOP是一种面向切面的技术思想,而JDK动态代理和第三方库CGLIB是实现AOP的技术手段
【1】JDK动态代理
(1)目标对象:必须实现一个或多个接口,常常是执行业务的方法(crud)的操作类
(2)逻辑增强:实现IvocationHandler接口,构造器获取目标对象,重写invoke方法,在方法内添加增强逻辑,如日志记录,事务实现,权限控制,通过形参的目标对象的方法反射对象method执行原始方法
(3)代理对象:调用Proxy.newProxyInstance(类加载器、目标类接口、增强逻辑)整合目标对象和增强逻辑到一个代理类对象中
通过InvocationHandler接口将代理逻辑(增强代码)与目标对象的方法调用绑定,具体流程:
1,代理类重写接口所有方法,这些方法都只包含一个逻辑:通过反射获取目标类型的method对象
2,将目标对象的方法调用(获取到的method对象)转发给InvocationHandler的invoke方法
3,然后执行代理逻辑(invoke上下)输出日志、执行method对象所对应的原始方法、输出日志
【2】CGLIB库:一个第三方库,通过生成目标类的子类作为代理类实现动态代理,是Spring在没有实现接口类的AOP的一种实现方式。
2648

被折叠的 条评论
为什么被折叠?



