面试问AOP的原理是什么,大家怎么回答
解决方案 »
- Java中BufferedWriter里的append与write有什么区别?
- ssh框架的structs-config.xml报错
- 关于生成java源码的问题
- struts2传递出现乱码问题
- 静态网页文章分页功能
- 在Struts的DTO里,为什么要用构造函数复制
- 那位servlet熟悉者帮我解决Services配置问题?web.xml
- 为何在tomcat 的启动过程中,一个实现了 ServletContextListener 接口的类会被调用两次。。。
- 用XML做网站的问题?
- 关于ibatis的 Mapped Statements collection does not contain问题
- dom4j生成XML文件里中文乱码,console里显示正常,怎么解决
- 求 Struts2 XSS解决方案
AOP底层的东西就是JDK动态代理和CGLIB代理,说白了就是增强类的功能。
最常用的AOP应用在数据库连接以及事务处理上。
AOP的应用:Spring声明式事务.
AOP通知的类型有:前通知,后通知,环绕通知,异常通知
因为他问的是原理,而不是AOP是什么,AOP的作用,AOP常用语哪些地方记得不要多说什么,面试官问什么,你答什么
触法点,也就是我们对应相应的业务写的方法,这些方法需要开启和关闭事务,我们把需要处理的方法叫做触法点,把这些出发点集合配置起来,这样更多的触法点就组成了一个触法面。
这里可以仔细想一下,和我们生活中的渔网差不多,一个网节就是一个触发点(代表一个方法);网就像是一个切面一样!
还有就是通知 这里就是在触法上面的触法点以后,就会有相应的:
前通知(在这里是一个开启事务的方法),也就是开启事务(这里是aop的一个监听,当它监听到触法时间后,就是停止执行出发点方法,先去调用前通知方法,达到开启事务);
环绕通知 就是事务回滚方法(监听到方法出现异常,就会执行环绕通知指定的方法)
后通知 就是也就是事务提交方法(监听到方法执行结束,就会执行通知指定的方法)
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");
}
}
不改变原代码,去增加新功能.
原来我今天在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通知的类型有:前通知,后通知,环绕通知,异常通知 是一种反射机制。原理就是“拦截”
小结:
因为今天刚学忍不住不做了一下笔记,好巧哦,又在上面看到理论,一下子感觉好清楚...看来光会操作也是不行的,做了半天连做的是什么都不知道,哎,太丢脸了!!
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....... 你背给它听,晕死他,你就过关了 哈.
他里面有几个专业术语,切面,切点,连接点,通知(advice),通知的类型。我做这样一个比喻,程序里面所有要执行拦截的方法比做一棵树,而切面比作一把斧子,而切点就是在树的哪一点砍(如树根,树干,树枝),通知类型就是将砍树位置在具体一下,是切点的上面(before)下面(after) 或是环绕(round)着砍,通知就是怎么在砍之前做一些其他的动作比如大吼两声什么的。 呵呵 ,以上是我自己的看法,有不足之处敬请指正。
jdk就能实现 aop的功能!
说到原理还真答不上来,看看jdk那个的原理把
2、如在实际应用有3个模块,模块一,模块二,模块三已经开发完成,新的需求要在模块一,模块二,模块三添加新功能(例如风险提示等),这个新功能用模块四代替,那么用AOP原理,模块四横切模块一,模块二,模块三实现新需求!
可以在一个事务管理器内发生两个事务也可以发生一个。
可以在方法前发生。也可以在方法后发生。
CGLIB用于对类的代理,是动态产生一个继承被代理类的类。
也可以手动选择CGLIG实现等
Spring AOP的核心设计思想:代理模式
AOP术语:目标对象(Target)通知(Advice)织入(Weaving)代理(Proxy)连接点(Joinpoint)切点(Pointcut)切面(Aspect)
AOP目标:专心做事
AOP原理
将散布在系统中的公共功能集中解决
AOP实现
采用一个机制
1. 将复杂的需求分解出不同方面
2. 专心做事
3. 组装起来运行
在开发软件项目时,有很多功能或服务如日志服务、事务管理和安全,会被融入到其他的模块中,
使编程代码出现了双重复杂性。
使用AOP,可以在系统中提升业务的分离,使系统功能和服务模块化,并把它们声明在需要用的地方,实现系统业务的代码在多个组件中复制。
OOP是横向集合AOP是纵向延伸。
声明一点:AOP与Spring没有关系,Spring 只是实现了AOP模式...而且是目前最好的实现..