SpringAOP,SpringIOC

IOC:
IOC,Inversion of control,控制反转,是Spring Core的核心,IOC并不能算作一种技术,而是一种思想,要知道控制反转,就必须先连接DI,依赖注入,因为控制反转就是由DI实现的,我们以设计一个行李箱来说明,我们一般设计行李箱的流程为:

 我们的设计思路是根据轮子设计底盘,根据底盘设计箱体,再根据箱体设计行李箱。这里面有以下的依赖关系,行李箱依赖箱体,箱体依赖于底盘,底盘依赖于轮子,这样设计的代码可维护性低,假如这时候提出需求,要将轮子的尺寸改大一码,这时候所有的代码都需要改了,代价是很高的,这时候我们使用依赖注入,所谓的依赖注入就是:把底层类作为参数,传递给上层类,实现上层对下层的控制,设计行李箱的过程变成如下图所示:

 我们先根据行李箱的大小来设计箱体,根据箱体来设计底盘,根据底盘来设计轮子,假如这时候的需要求是要求改轮子的大小,就不需要改其他部分的代码,只需修改轮子部分的代码即可。即将底层注入到上层。

AOP:即面向切面编程,可以说是对面向对象编程的补充和完善,面对对象编程引入封装,继承,多态等概念来建立一种对象层次结构,允许开发者定义纵向的关系,但并不适合定义横向的关系,比如日志功能,如果硬是要使用面对对象对象来进行实现日志的功能的话,势必导致项目的重复代码的增多,且进行维护时的难度加大。AOP技术恰恰相反,它利用一种称为横切的技术,剥解开封装对象的内部,将哪些影响了多个类的公共行为封装到一个可重用模块,并将其命名为切面,所谓切面,就是将哪些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码。降低模块之间的耦合度。例如我们要在一个保存数据到数据的方法中要进行权限验证。我们传统解决方法一:是编写一个可重复调用方法,各模块进行调用即可,方法二:是我们可以将这个方法封装到一个类中,然后要使用这个方法的类就继承这个类即可,但是这样的代码重复率高和维护难度大,我们采用AOP的方式,就可以解决上诉解决方法的缺点。

AOP用法:

jdk动态代理:只能对实现接口的类产生代理对象,必须是实现接口的类才能用jdk动态代理

假设我们现在有一个接口UseDao,和一个它的实现类UseDaoImpl,接口里面有一个save方法,作用是保存数据,但现在我们要实现在保存之前做一些类似权限验证的操作,

package DynamicProxy;
//接口
public interface UserDao {
    public  void save();
}

//实现类

public class UserDaoImpl implements  UserDao{
        public  void save(){
            System.out.println("保存。。。");
        }
}
代理类
/**
 * 使用JDK动态代理对UserDaoImpl产生代理
 */
public class JdkProxy implements InvocationHandler {
    //将被增强的对象传递到代理中
    public   UserDao userDao;
    public  JdkProxy(UserDao userDao){
        this.userDao=userDao;
    }
    /**
     * 产生UserDaoImpl代理的方法
     * @return
     */
    public UserDao createProxy() {
        /**
         * 第一个参数:类加载器,对谁产生代理,这个类加载就是加载谁的
         * 第二个参数:接口,实际上传的是实例
         * 第三个参数:InvocationHandler,真正执行方法的对象
         */
        UserDao userDaoProxy= (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(),this);
        return  userDaoProxy;
    }

    /**
     *
     * @param proxy   代理对象
     * @param method  正在执行的方法
     * @param args    方法参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         //判断方法是否是我们需要增强的
         if("save".equals(method.getName())){
             //增强
             System.out.println("权限校验");
             return method.invoke(userDao,args);
         }
        return method.invoke(userDao,args);
    }
}
//测试
public class TestProxy {
    @Test
   public    void save(){
        UserDao userDao=new UserDaoImpl();
        //创建代理
        UserDao userDaoproxy=new JdkProxy(userDao).createProxy();
        userDaoproxy.save();
    }
}

Cglib产生代理对象:
对没有实现接口的类产生代理对象,生成子类对象

//具体类,而不是接口了
public class CustomerDao {
   public void save(){
       System.out.println("保存。。。");
   }
}

//产生代理的类
public class CglibProxy implements MethodInterceptor {
    private  CustomerDao customerDao;
    public  CglibProxy(CustomerDao customerDao){
        this.customerDao=customerDao;
    }
    /**
     * 使用Cglib产生代理的方法
     */
    public CustomerDao createProxy(){
        //1.创建Cglib核心类的对象
        Enhancer enhancer=new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(customerDao.getClass());
        //3.设置回调(类似于InvocationHandler对象)
        enhancer.setCallback(this);
        //4.创建代理对象
        CustomerDao proxy = (CustomerDao) enhancer.create();
        return  proxy;

    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        //判断方法是否是我们需要增强的
        if("save".equals(method.getName())){
            //增强
            System.out.println("权限校验");
            return methodProxy.invokeSuper(proxy,args);
        }
        return methodProxy.invokeSuper(proxy,args);
    }
}
//测试
@Test
    public void  save2(){
        CustomerDao customerDao=new CustomerDao();
        CustomerDao proxy = new CglibProxy(customerDao).createProxy();
        proxy.save();
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值