面试问AOP的原理是什么,大家怎么回答

解决方案 »

  1.   

    面向切面编程,把散落在程序中的公共部分提取出来,做成切面类,这样的好处在于,代码的可重用,一旦涉及到该功能的需求发生变化,只要修改该代码就行,否则,你要到处修改,如果只要修改1、2处那还可以接受,万一有1000处呢。
    AOP底层的东西就是JDK动态代理和CGLIB代理,说白了就是增强类的功能。
    最常用的AOP应用在数据库连接以及事务处理上。
      

  2.   

    可以谈谈“反射机制”。aop、依赖注入都是给予“反射”的。
      

  3.   

    AOP是面向切面编程,是通过代理的方式为程序添加统一功能,集中解决一些公共问题。
    AOP的应用:Spring声明式事务.
    AOP通知的类型有:前通知,后通知,环绕通知,异常通知
      

  4.   

    我倒觉得AOP干的事情比较像方法重载,因为他就是建立在方法上,通过它提供的各种通知,能让方法变得更灵活,需求有改动不能改源码,改通知类就行
      

  5.   

    4 楼 11楼 正解,  类似安全验证、事物等问题,与我们编写程序要实现的功能没有关系,这类问题可称之为切面性问题,aop主要是利用代理机制解决这类问题的,使程序员只专注于业务的开发,从事务提交等与业务无关的问题中解脱出来。主要是反射机制。
      

  6.   

    恩 我也 一下 谢谢jdk动态代理
      

  7.   

    面向却面编程。依赖注入,ioc容器
      

  8.   

    原理四个字:代理模式别的不要多说,装深沉,别人以为你是高手,多说了,就露馅了
    因为他问的是原理,而不是AOP是什么,AOP的作用,AOP常用语哪些地方记得不要多说什么,面试官问什么,你答什么
      

  9.   

    Aop面向方面的开发,不如说是面向切面开发!在Spring里面aop的事务代理机制主要体现在!
    触法点,也就是我们对应相应的业务写的方法,这些方法需要开启和关闭事务,我们把需要处理的方法叫做触法点,把这些出发点集合配置起来,这样更多的触法点就组成了一个触法面。
    这里可以仔细想一下,和我们生活中的渔网差不多,一个网节就是一个触发点(代表一个方法);网就像是一个切面一样!
    还有就是通知  这里就是在触法上面的触法点以后,就会有相应的:
    前通知(在这里是一个开启事务的方法),也就是开启事务(这里是aop的一个监听,当它监听到触法时间后,就是停止执行出发点方法,先去调用前通知方法,达到开启事务);
    环绕通知 就是事务回滚方法(监听到方法出现异常,就会执行环绕通知指定的方法)
    后通知  就是也就是事务提交方法(监听到方法执行结束,就会执行通知指定的方法)
      

  10.   

    给LZ贴段代码,你在本地跑跑,你就明白了。package net.chinacsharp.jdf.clent;import java.util.HashMap;import net.chinacsharp.jdf.cache.Cache;
    import net.chinacsharp.jdf.exception.JDFException;
    import net.chinacsharp.jdf.interfaces.IServiceFactoryInterface;/**
     * 服务工厂,代理业务系统服务,通过代理切口实现事务自动控制
     * @author keyboardsun
     *
     */
    public class ServiceFactory{  /**
       * 获得代理过后的服务
       * @param paramString
       * @return
       * @throws JDFException
       * @throws IllegalAccessException
       * @throws InstantiationException
       * @throws ClassNotFoundException
       */
      public static Object getService( String paramString ) throws  JDFException, IllegalAccessException, InstantiationException, ClassNotFoundException{
        HashMap map = Cache.getService();
        String[] service = (String[]) map.get(paramString);
        if(service==null){
          throw new JDFException("service :\""+paramString+"\" is not found");
        }    
        return ProxyFactory.getReflectProxy(Class.forName(service[1]).newInstance());
      }}package net.jkf.mysql;import java.util.HashMap;public interface ITest{
      public void test1(String name,String good);
      public void test2(HashMap m,String s);
      
    }
    package net.jkf.mysql;import java.util.HashMap;import net.chinacsharp.jdf.clent.BeanEngine;
    import net.chinacsharp.jdf.datastore.jdbctool.ConnectionHelper;
    import net.chinacsharp.jdf.init.ConnectPropertiesInit;
    import net.chinacsharp.jdf.init.InitFrameWork;
    import net.chinacsharp.jdf.interfaces.IConnectionHelper;public class Test
        implements ITest{  public void test1( String name, String good ){
       
        System.out.println("调用过来了"+name);  }  public void test2( HashMap m, String s ){
        System.out.println("调用过来了"+m);  }
    }
    package net.jkf.mysql;import java.util.HashMap;import net.chinacsharp.jdf.clent.ServiceFactory;
    import net.chinacsharp.jdf.exception.JDFException;
    import net.chinacsharp.jdf.init.ServiceXmlInit;
    import net.chinacsharp.jdf.proxy.proxyfactory.*;public class ProxyFactoryTest{
      public static void main(String args[]) throws JDFException, IllegalAccessException, InstantiationException, ClassNotFoundException{
      new ServiceXmlInit().execute();
      ITest t = (ITest)ServiceFactory.getService("net.jkf.mysql.Test");
      t.test1("sunlei","mininlal");
      HashMap m = new HashMap();
      m.put("good","nice");
      t.test2(m,"mininlal");
      }
      
    }
    package net.chinacsharp.jdf.clent;
    /**
     * 给客户端提供使用的代理小工具
     * @author keyboardsun
     *
     */
    public class ProxyFactory{  /**
       * 这里如果给的object 不是继承接口的,会报IllegalArgumentException,然后用cglib获取代理
       * @param o
       * @return
       */
      public static Object getProxyOjbect(Object o){    
        try{
          return net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory.newInstance(o);
        } catch (IllegalArgumentException e) {
          return net.chinacsharp.jdf.proxy.cglib.ProxyFactory.getInstance(o.getClass());
        }    
      }  
      
      /**
       * 获取传统代理
       * @param o
       * @return
       */
      public static Object getReflectProxy(Object o){
        return net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory.newInstance(o);
      }
      /**
       * 获cglib统代理
       * @param o
       * @return
       */
      public static Object getCglibProxy(Class c){
        return net.chinacsharp.jdf.proxy.cglib.ProxyFactory.getInstance(c);
      }
    }
    package net.chinacsharp.jdf.proxy.proxyfactory;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;import net.chinacsharp.jdf.datastore.jdbctool.ConnectionHelper;
    import net.chinacsharp.jdf.interfaces.IConnectionHelper;import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;/**
     * 传统的代理工厂
     * @author keyboardsun
     *
     */
    public class ProxyFactory
        implements InvocationHandler{
      private static transient Log log = LogFactory.getLog( ProxyFactory.class );
      private Object obj = null;// 这里原装的对象  public ProxyFactory( Object o ){
        obj = o;
        log.debug( "代理了一个类噢:" + o.getClass().getName() );
      }  /**
       * 代理的方法都经过这里调用
       * @param arg0
       * @param m
       * @param parms
       * @return
       * @throws Throwable
       */
      public Object invoke( Object arg0, Method m, Object[] parms ) throws Throwable{
        long beginTime = System.currentTimeMillis();    
        Object o = null;
        IConnectionHelper helper = new ConnectionHelper();
        try{
          o = m.invoke( obj, parms );
          log.debug( "invoke method is :" + m.getName() );
          for( int i = 0; i < parms.length; i++ ){
            log.debug( "invoke parms is :" + parms[i].toString() );
          }
          long endTime = System.currentTimeMillis();
          log.debug("invoke class is :"+obj.getClass().getName()+" invoke method is:"+m.getName()+"  invoke time is:"+(endTime-beginTime)+" ms");
          helper.commitConnection();
          return o;
        }catch( Exception e ){
          helper.rollbackConnection();
          // TODO 这里事务回滚,NND,不知道可以否
          throw e;
        }
         }  public static Object newInstance( Object o ){
        InvocationHandler handler = new ProxyFactory( o );
        ClassLoader cl = o.getClass().getClassLoader();
        Class c = null;
        //因为这里代理只能用接口
        if( o.getClass().isInterface() ){
          c = o.getClass();
        }else{
          Class[] interfaces = o.getClass().getInterfaces();
          if( interfaces != null && interfaces.length > 0 ){
            c = interfaces[0];
          }
        }
        return Proxy.newProxyInstance( cl, new Class[] {c}, handler );
      }}
    package net.jkf.mysql;import java.util.HashMap;import net.chinacsharp.jdf.clent.ServiceFactory;
    import net.chinacsharp.jdf.exception.JDFException;
    import net.chinacsharp.jdf.init.ServiceXmlInit;
    import net.chinacsharp.jdf.proxy.proxyfactory.*;public class ProxyFactoryTest{
      public static void main(String args[]) throws JDFException, IllegalAccessException, InstantiationException, ClassNotFoundException{
      new ServiceXmlInit().execute();
      ITest t = (ITest)ServiceFactory.getService("net.jkf.mysql.Test");
      t.test1("sunlei","mininlal");
      HashMap m = new HashMap();
      m.put("good","nice");
      t.test2(m,"mininlal");
      }
      
    }
      

  11.   

    jdk的动态代理
      

  12.   

    AOP (Aspect Oriented Programming) 面向方面的实现,OOP的延伸,可以说是用于解决一些特有问题的方案,将通用需求功能从不相关类之中分离出来;同时,能够使得很多类共享一个行为,一旦行为发生变化,不必修改很多类,只要修改这个行为就可以。 AOP就是这种实现分散关注的编程方法,它将“关注”封装在“方面”中。 原理这个说法有点离异!!
      

  13.   

    aop的原理(动态代理)
       不改变原代码,去增加新功能.
      

  14.   

    好巧哦,我今天就是在学这个AOP呢,最重要的是我并不知道我今天学的东西叫AOP,只是会操作而已...
    原来我今天在spring框架下做的那个玩意叫AOP呀。。但我学了之后就是感觉它在做日志,事务呀方面有点用,别的就没感觉了...
    操作:
    而那四个通知啊:前通知,后通知,环绕通知,异常通知
    我分别实现了三个,还有一个老师说有点烦,就没有做。嗯,好像是异常通知
    啊对了,在配那个applicationcontext.xml时有点烦,不过它最大的优势好像也体现在这里的样子,
    有一代理类一定要在bean里写进去哦,<bean id="*" class="org.springframework.aop.framework.ProxyFactoryBean"></bean>
     然后就是做这种aop的项目一定要写接口,因为这里的代理类中,接口是作为一个参数的.property一共有3个参数如下:
      <property name="interfaces" class="接口类"></property>//如果你建了接口interfaces是有提示的
       <property name="target" ref="接口实现类"></property>//target有提示
        <property name="interceptorNames">//interceptorNames有提示,这就是拦截器
       <list>
       <value>这就是具体实现的通知的类,一般会在上面建一个bean</value>
       <value>.....</value>
       ....有几个通知就有几个value
       </list>
       </property>
       </property>
    这句话概括的很好哦;Spring声明式事务
     理论: 
     AOP是面向切面编程,是通过代理的方式为程序添加统一功能,集中解决一些公共问题。 
     AOP的应用:Spring声明式事务. 
     AOP通知的类型有:前通知,后通知,环绕通知,异常通知 是一种反射机制。原理就是“拦截”
    小结:
     因为今天刚学忍不住不做了一下笔记,好巧哦,又在上面看到理论,一下子感觉好清楚...看来光会操作也是不行的,做了半天连做的是什么都不知道,哎,太丢脸了!!
      

  15.   

    aop是面向切面编程,它的目的和原理是把所有类似的问题提取出来,统一解决和实现,这样就避免了在每个有此类问题的地方编写大量重复的代码,有点像过滤器
      

  16.   

    spring in action 2th Edition:
        Aspect-oriented programming is often defined as a programming technique that
    promotes separation of concerns within a software system. Systems are composed
    of several components, each responsible for a specific piece of functionality.
    Often, however, these components also carry additional responsibility beyond
    their core functionality. System services such as logging, transaction management,
    and security often find their way into components whose core responsibility is
    something else. These system services are commonly referred to as cross-cutting
    concerns because they tend to cut across multiple components in a system.
    ......   你背给它听,晕死他,你就过关了 哈.
       
      

  17.   

    aop 其实是面向切面编程的,他一些横切性的东西集中起来进行管理,比如说事物,日志,权限,他的原理就是动态代理(如果动态代理部明白的话可以去看以下代理模式)他的好处就是,代码比较清晰,减少了代码的重复。如果不用aop你需要将这些横切性的东西都在每个方法里面写一遍。
    他里面有几个专业术语,切面,切点,连接点,通知(advice),通知的类型。我做这样一个比喻,程序里面所有要执行拦截的方法比做一棵树,而切面比作一把斧子,而切点就是在树的哪一点砍(如树根,树干,树枝),通知类型就是将砍树位置在具体一下,是切点的上面(before)下面(after) 或是环绕(round)着砍,通知就是怎么在砍之前做一些其他的动作比如大吼两声什么的。 呵呵 ,以上是我自己的看法,有不足之处敬请指正。
      

  18.   

    代理模式 
    jdk就能实现 aop的功能!
    说到原理还真答不上来,看看jdk那个的原理把 
      

  19.   

    1、面向切面编程
    2、如在实际应用有3个模块,模块一,模块二,模块三已经开发完成,新的需求要在模块一,模块二,模块三添加新功能(例如风险提示等),这个新功能用模块四代替,那么用AOP原理,模块四横切模块一,模块二,模块三实现新需求!
      

  20.   

    我的观点其实就是拦截方法。可以的aop的事务管理器内也可以在外。
    可以在一个事务管理器内发生两个事务也可以发生一个。
    可以在方法前发生。也可以在方法后发生。
      

  21.   

    建议看一下林信良老师的那本spring技术手册 个人认为写的很清楚了
      

  22.   

    JDK动态Proxy用于对接口的代理,是动态产生一个实现指定接口的类
    CGLIB用于对类的代理,是动态产生一个继承被代理类的类。
      

  23.   

    说白了AOP的功能就是在指定的方法的前后插入想要附件运行的方法底层实现默认使用的是JDK动态代理。
    也可以手动选择CGLIG实现等
      

  24.   

    Aspect Oriented Programming(AOP)面向方面的编程(面向切面的编程)
    Spring AOP的核心设计思想:代理模式
    AOP术语:目标对象(Target)通知(Advice)织入(Weaving)代理(Proxy)连接点(Joinpoint)切点(Pointcut)切面(Aspect)
    AOP目标:专心做事
    AOP原理
    将散布在系统中的公共功能集中解决
    AOP实现
    采用一个机制
    1. 将复杂的需求分解出不同方面
    2. 专心做事
    3. 组装起来运行
      

  25.   

      aop的精髓都说出来了
      

  26.   

    现在还不明白AOP是怎么实现的,看来该找本专门讲解AOP的书来看看了
      

  27.   

    前一段老师刚讲的 用动态代理模拟实现spring的AOP
      

  28.   

    这个是OOP的补充,把不同模块的相同功能做成提取出来做成所谓的切面,使程序更加模块化。
      

  29.   

    与OOP相对应,OOP的继承解决上下级父子之间的代码重用,AOP是水平级兄弟之间的代码重用
      

  30.   

    AOP是Aspect Oriented Programming的缩写,是“面向方面编程”的意思。
    在开发软件项目时,有很多功能或服务如日志服务、事务管理和安全,会被融入到其他的模块中,
    使编程代码出现了双重复杂性。
    使用AOP,可以在系统中提升业务的分离,使系统功能和服务模块化,并把它们声明在需要用的地方,实现系统业务的代码在多个组件中复制。
      

  31.   

    AOP是OOP的延续,
       OOP是横向集合AOP是纵向延伸。
    声明一点:AOP与Spring没有关系,Spring 只是实现了AOP模式...而且是目前最好的实现..
      

  32.   

    程序就是一个大饼,你要带芝麻的,aop就在外面给你弄上芝麻,而大饼不需要重新做,你要葱花呢,就给你弄点葱花,大饼还是不用重新做。用了aop后 大饼就是多味道的大饼了。嘿嘿