一、Spring IOC(DI)
1、概念:IOC:控制反转,这是一个过程,DI:依赖注入,是这个过程中的具体方法。
2、实现:IOC 大量的运用反射机制,通过解析你在xml里配置的类名方法名生成对象,然后返回给调用者。
3、java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用他的合作对象时,自己均要使用像new object() 这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。
二、Spring AOP
1、概念
AOP(Aspect-Oriented Programming)其实是OOP(Object-Oriented Programing)思想的补充和完善。我们知道,OOP引进"抽象"、"封装"、"继承"、"多态"等概念,对万事万物进行抽象和封装,来建立一种对象的层次结构,它强调了一种完整事物的自上而下的关系。但是具体细粒度到每个事物内部的情况,OOP就显得无能为力了。比如日志功能。日志代码往往水平地散布在所有对象层次当中,却与它所散布到的对象的核心功能毫无关系。对于其他很多类似功能,如事务管理、权限控制等也是如此。这导致了大量代码的重复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为"横切"的技术,能够剖解开封装的对象内部,并将那些影响了多个类并且与具体业务无关的公共行为 封装成一个独立的模块(称为切面)。更重要的是,它又能以巧夺天功的妙手将这些剖开的切面复原,不留痕迹的融入核心业务逻辑中。这样,对于日后横切功能的编辑和重用都能够带来极大的方便。
AOP技术的具体实现,无非也就是通过动态代理技术或者是在程序编译期间或修改编译后代码来进行静态的"织入"方式。
2、静态代理和 动态代理
(1)静态代理:
public interface AInterface{
public void say();
}
真实A:
public class A implements AInterface{
public void say(){
System.out.println("真实A 被调用了");
}
}
代理A:
public class AProxy implements AInterface{
//持有一个真实A对象的引用
private A a;
//销售总量
private static int sell_count = 0;
public void say(){
if(check()){//在代理类里,我们可以在真实A被调用前做一些诸如权限判断的事情
a.say();
}else{
System.out.println("此阶段不能说话");
}
}
protected boolean check(){
//do something return true;
}
}
(2)动态代理:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*代理类一定要实现了InvocationHandler接口
*/
public class B implements InvocationHandler{
private Object proxy_obj;
B(Object obj){ //把真实A的对象传进来
this.proxy_obj = obj;
}
public static Object factory(Object obj){
Class cls = obj.getClass();
//通过Proxy类的newProxyInstance方法来返回代理对象 ,
//返回的这个对象是extend Proxy 并implements AInterface
return Proxy.newProxyInstance(cls.getClassLoader(),
cls.getInterfaces(),new ProxyObject(obj));
}
/**
*实现InvocationHandler接口的invoke
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("函数调用前被拦截了: " + method);
if(args != null){
//打印参数列表
System.out.println("方法有 " + args.length + " 个参数");
for(int i = 0; i < args.length; i ++){
System.out.println(args[i]);
}
}
//利用反射机制动态调用原对象的方法
Object mo = method.invoke(proxy_obj, args);
System.out.println("函数调用后进行处理 : " + method);
return mo;
}
//测试代码
public static void main(String agr[]){
AInterface ai = (<span style="font-family: Arial, Helvetica, sans-serif;">AI</span><span style="font-family: Arial, Helvetica, sans-serif;">nterface)factory(new A()); </span>
ai.sell(); //此时的 cell 就会输出拦截前后的日志了
}
}
(3)静态代理和动态代理的区别:
Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。
CGLIB(Code Generation Library),简单来说,就是一个代码生成类库。它可以在运行时候动态是生成某个类的子类。