参考文章:https://www.cnblogs.com/wmyskxz/p/8820371.html
Spring的核心是控制反转(IoC)和面向切面(AOP)
控制反转:将创建对象的控制权,交由Spring框架来管理。
若要使用某个对象,只需要从 Spring 容器中获取需要使用的对象,不用关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架
即:所以的类都在ApplicationContext.xml文件中配置好,使用时只需要通过ClassPathXmlApplicationContext这个对象获取就行
如下:
配置:
使用:
DI:Dependency Injection(依赖注入)
- 指 Spring 创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象
IoC 和 DI 其实是同一个概念的不同角度描述,DI 相对 IoC 而言,明确描述了“被注入对象依赖 IoC 容器配置依赖对象”
AOP:面向切面编程,参考地址:http://www.cnblogs.com/xrq730/p/4919025.html
关于面向切面编程的一些术语:
- 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
- 切面(Aspect): 切面用于组织多个Advice,Advice放在切面中定义。
- 连接点(Joinpoint): 被拦截到的点。在Spring AOP中,连接点总是方法的调用。
- 增强处理(Advice): 指拦截到连接点之后要执行的代码。AOP框架在特定的切入点执行的增强处理。处理有"around"、"before"和"after"等类型
- 切入点(Pointcut): 对连接点进行拦截的定义。可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
在网上找到这张图,描述的还是比较形象的:
AOP的本质是在一系列纵向的控制流程中,把那些相同的子流程提取成一个横向的面。
若使用AOP,除了使用Spring自带的jar包,还需要在网上下载aspectjweaver.jar。
首先创建一个业务类接口MainService:
package service;
public interface MainService {
public void doSomeService();
}
然后实现这个业务类:
public class MainServiceImp implements MainService {
@Override
public void doSomeService() {
System.out.println("do some service");
}
}
添加横切关注点LogAspect,打印日志:
public class LogAspect {
public void logBefore() {
System.out.println("log before method");
}
public void logAfter() {
System.out.println("log after method");
}
}
代码添加完成后,在配置文件中进行配置:
<bean id="mainService" class="service.MainServiceImp"/>
<bean id="logAspect" class="service.LogAspect"/>
<aop:config>
<aop:aspect id="log" ref="logAspect">
<aop:pointcut id="printlog" expression="execution(* service.MainService.*(..))" />
<aop:before method="logBefore" pointcut-ref="printlog" />
<aop:after method="logAfter" pointcut-ref="printlog" />
</aop:aspect>
</aop:config>
配置成功后,无需再做其他的操作,只要正常调用核心业务即可启动日志切面的功能。
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"applicationContext.xml"}
);
MainService mainService = (MainService) context.getBean("mainService");
mainService.doSomeService();
打印结果如下:
在核心业务的前面和后面都调用了横切的方法。