IoC和AOP
IoC简介:
1.Inversion of Control 控制反转。一种设计思想,为了降低耦合度。通过反射机制实现。
2.A实例调用B实例,通常是A通过new B来创建B实例,从而调用;而在依赖注入的模式下创建被调用者的工作不再由调用者来完成,而是通过Spring来创建,因此称之为“控制反转”;获得依赖对象的过程被反转了。
3.DI: Dependency Injection 依赖注入:由IoC容器在运行期间,动态地把底层类对象作为参数传入(注入)上层类。DI在IoC的基础上完成。
4.IoC容器类似于工厂模式中生产对象的工厂类Factory:根据类名(配置文件或者对象的),通过反射动态生成具体对象。
IoC两种方式:
1.配置文件方式注入(手动装配): 有参构造方法注入属性(constructor-arg标签)、通过Setter方法注入(property标签+value)、注入对象型属性(property标签+ref)等。 实现原理: xml配置文件+dom4j解析+工厂模式+反射; 默认scope是单例。
2.注解方式注入(自动装配): <context:component-scan base-package="com.xxx.xxx"/> 开启注解扫描。
注解原理:1.用反射获取当前类的所有属性; 2.遍历所有属性,判断是否存在注解; 3.查找bean容器对象,给有注解的属性赋值。
@Component 等价于: <bean class=""> @Component("id") 等价于: <bean id="" class="">
@Component的衍生注解: @Repository :dao层 @Service:service层 @Controller:web层
@Autowired:自动注入或自动装配,根据类名找对应的对象完成注入。
创建对象的操作一般用配置文件方式,注入属性的操作一般用注解方式。
AOP简介:
1. Aspect Oriented Programming 面向切面编程。通过预编译方式和运行期动态代理,实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。利用代理模式实现。
2.AOP的主要功能是:日志记录,性能统计,安全控制,事务处理,异常处理等。
3.术语:1.target 目标类:需要被代理的类。
2.joinPoint 连接点:可能被拦截到的方法。
3.pointCut 切入点:已经被增强的连接点(方法)。
4.advice 通知/增强:增强的代码(before/after)。
5.weaving 织入:把增强(advice)应用到目标类(target)来创建新的代理对象(proxy)的过程。
6.proxy 代理类
7.aspect 切面:切入点(pointCut) + 增强(advice)。
4.<aop:aspectj-autoproxy proxy-target-class="true"/> 表示支持注解的AOP。proxy-target-class默认为false,表示用jdk动态代理织入增强(没实现接口,则还是用cglib),设置为true时表示都用cglib。
AOP底层原理:代理模式
四种实现方式:手动方式,半自动方式,全自动方式,注解方式
1.手动方式: JDK动态代理
cglib动态代理:使用asm字节码生成框架,生成代理类的字节码
2.半自动方式:让spring 容器创建代理对象,从spring容器中手动的获取代理对象
3.全自动方式:从spring 容器获得目标类,如果配置aop,spring将自动生成代理。项目中用的这种。
4.注解方式: @AspectJ
项目中的使用:
1.动态数据源配置:基于注解的多数据源配置、AOP方式实现多数据源切换
2.aop拦截: 统一日志处理、统一异常处理:
1.定义切面类:实现MethodInterceptor接口,重写invoke方法做环绕增强(接口计时、记录入参出参、超过200ms打warn日志等);
2.在applicationContext.xml中增加aop配置:
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<!-- 配置需要进行方法拦截的文件:以Service和Repository结尾的类 -->
<list>
<value>*Repository</value>
<value>*Service</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>exceptionHandler</value> <!-- 统一异常处理 -->
<value>logInterceptor</value> <!-- 统一日志处理 -->
</list>
</property>
</bean>