Ⅰ 什么是面向切面编程
Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。比如我们最常见的就是日志记录了,举个例子,我们现在提供一个查询学生信息的服务,但是我们希望记录有谁进行了这个查询。如果按照传统的OOP的实现的话,那我们实现了一个查询学生信息的服务接口(StudentInfoService)和其实现 类 (StudentInfoServiceImpl.java),同时为了要进行记录的话,那我们在实现类(StudentInfoServiceImpl.java)中要添加其实现记录的过程。这样的话,假如我们要实现的服务有多个呢?那就要在每个实现的类都添加这些记录过程。这样做的话就会有点繁琐,而且每个实现类都与记录服务日志的行为紧耦合,违反了面向对象的规则。那么怎样才能把记录服务的行为与业务处理过程中分离出来呢?看起来好像就是查询学生的服务自己在进行,但却是背后日志记录对这些行为进行记录,并且查询学生的服务不知道存在这些记录过程,这就是我们要讨论AOP的目的所在。AOP的编程,好像就是把我们在某个方面的功能提出来与一批对象进行隔离,这样与一批对象之间降低了耦合性,可以就某个功能进行编程。
Ⅱ Java编程中的AOP和IOC分别是什么呢,什么时候用呢
控制反转(IOC)
(理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”)
1、Ioc—Inversion of Control:即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
2、谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象即由Ioc容器来控制对象的创建。
谁控制谁?当然是IoC 容器控制了对象。
控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
3、为何是反转,哪些方面反转了: 有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象。
为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转。
哪些方面反转了?依赖对象的获取被反转了。
还是不明白没事,下面搞个简单案例来说就懂啦 !!!
例子:当我们在任何一个有实际开发意义的程序项目中,我们会使用很多类来描述他们特有的功能,并且通过类与类之间的相互协作来完成特定的业务逻辑。这个时候,每个类都需要负责管理与自己有交互的类的引用和依赖,代码将会变的异常难以维护和极高的高耦合。而IOC的出现正是用来解决这个问题,我们通过IOC将这些依赖对象的创建、协调工作交给spring容器去处理,每个对象值需要关注其自身的业务逻辑关系就可以了。在这样的角度上来看,获得依赖的对象的方式,进行了反转,变成了由spring容器控制对象如何获取外部资源(包括其他对象和文件资料等)。
总的来说:IOC就是通过在Xml配置文件里依赖注入来解决代码问题。
IOC的注入类型有几种?主要可以划分为三种:构造函数注入、属性注入和接口注入。Spring支持构造函数注入和属性注入
面向切面(AOP)
(面向切面编程,AOP其实只是OOP的补充而已,AOP基本上是通过代理机制实现的。)
我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。
我们都知道 Java 是 OOP-面向对象编程的,它有自己的优势,也有自己的不足。比如说:在我们开发中,都会有一条业务主线(即客户的需求)。而我们要做的就是实现这个主线上的需求。我们在实现这些功能的时候,经常要干一些额外的不可避免的事情,比如事务的管理,日志的记录等,就很繁杂且代码量增多,所以 Spring 提供了另一种角度来思考程序结构,也就是把这一些事情剥离出来,然后适时适地的把它们加入到我们的代码中,比如说 声明式事务管理的时候,我们在 service 层检测到save*、update*这些方法要被调用的时候,我们先进行开启事务什么的,这就是AOP,面向编程的思想。
AOP的术语:
1、通知(Advice):就是你想要的功能,也就是上面说的 安全,事物,日志等。你给先定义好把,然后在想用的地方用一下
2、连接点(JoinPoint):这个更好解释了,就是spring允许你使用通知的地方,那可真就多了,基本每个方法的前,后(两者都有也行),或抛出异常时都可以是连接点,spring只支持方法连接点.其他如aspectJ还可以让你在构造器或属性注入时都行,不过那不是咱关注的,只要记住,和方法有关的前前后后(抛出异常),都是连接点。
3、切入点(Pointcut):上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有几十个连接点了对把,但是你并不想在所有方法附近都使用通知(使用叫织入,以后再说),你只想让其中的几个,在调用这几个方法之前,之后或者抛出异常时干点什么,那么就用切点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。
4、切面(Aspect):切面是通知和切入点的结合。现在发现了吧,没连接点什么事情,连接点就是为了让你好理解切点,搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过方法名中的before,after,around等就能知道),而切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。
5、引入(introction):允许我们向现有的类添加新方法属性。这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗
6、目标(target):引入中所提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咱们织入切面。而自己专注于业务本身的逻辑。
7、代理(proxy):怎么实现整套aop机制的,都是通过代理,这个一会给细说。
8、织入(weaving):把切面应用到目标对象来创建新的代理对象的过程。有3种方式,spring采用的是运行时,为什么是运行时,后面解释。
Ⅲ Java核心技术:Spring是什么
从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 简单来说,Spring就是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 下面从整体上认识一下Spring的主要特征: *轻量:从大小与开销两方面而言Spring都是轻量的。此外,Spring是非侵入式的:使用Spring,我们的类还是pojo类,完全不用继承和实现Spring的类和接口等。 也就是说,使用Spring的应用中的对象不依赖于Spring的特定类。 *IoC:Spring通过控制反转技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。可以认为IoC与JNDI相反--不是我们自己控制对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它,这就是DI--依赖注入。 基本上就是对象不用自己动手管理和创建。完全由容器管理,我们只管用就行。 *AOP:Spring提供了面向切面的编程支持,AOP将与程序业务无关的内容分离提取,应用对象只实现它们应该做的--完成业务逻辑--仅此而已。它们并不负责其它的系统级关注点,例如日志或事务支持。 AOP将与业务无关的逻辑横切进真正的逻辑中。 *框架:Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),而用户就有更多的时间和精力去开发应用逻辑。 所有Spring的这些特征都能帮助我们够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。 *借助Spring,荣国依赖注入,AOP应用,面向接口编程,来降低业务组件之间的耦合度,增强系统的扩展性。 * 让已有的技术和框架更加易用。 *利用其对hibernate的SessionFactory、事务管理的封装,更简洁的应用hibernate. *Spring并不完全依赖于Spring,开发者可自由选用Spring框架的部分或全部 *利用AOP思想,集中处理业务逻辑,减少重复代码,构建优雅的解决方案。 *低侵入式设计,代码污染极低。 Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是企业应用开发的"一站式"选择,并贯穿表现层、业务层及持久层。 虽然Spring可以一站式解决整个项目问题,但是Spring并不想取代那些已有的框架,而是与它们无缝地整合。Spring可以降低各种框架的使用难度,他提供了对各种优秀框架(如Struts、Hibernate、Hessian、Quartz等)的直接支持。 使用Spring的主要目的是使J2EE易用和促进好的编程习惯,Spring的目标就是让已有的技术更加易用。 所以Spring的一个重要思想就是整合和兼容。
Ⅳ Spring中的AOP概念
spring的APO是指面向切面编程,它的主要实现原理主要两种。
1.通过Java动态代理(反射)机制,在要执行的方法前后,加上事务控制或日志。
2.通过修改Java字节码的方式,修改你编译好的类,在要执行的方法前后,加上事务控制或日志。
通知、切入点等其实就是用来配置在什么类、什么位置来执行、执行什么方法等。
掘尘
举个列子:
给下面的方法加孙散皮上日志记录:
publicvoidsave(Objectdata){
//保存到数据库逻辑
}
通过SpringAOP的方式配置日志后,最终程序执行时(也许是反射,也许是修改class),实则差际上在执行save(obj)时,执行了下面的逻辑:
log.info("开始保存");
save(obj);
log.info("结束保存");
Ⅳ java中的Spring里面的ioc和aop有什么区别他们都有什么用
IOC的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。Spring容器负责将这些联系在一起。也就是说,Spring的IOC负责管理各种对象的创建、清除以及它们之间的联系。AOP是指面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。一般用于事务管理、权限控制、错误处理等各种业务中共同性的东西。
Ⅵ 使用java语言,如何对一个类中的静态方法做切面编程
packagecom.classloader.test;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
importjava.lang.reflect.Modifier;
{
privateCallBackcallBack;
publicAOPCallStaticMehtod(CallBackcallBack){
this.callBack=callBack;
}
publicstaticinterfaceCallBack{
voidbefore(Methodmethod);
voidafter(Methodmethod,Objectresult);
}
@SuppressWarnings({"unchecked","rawtypes"})
publicObjectcallMethod(Classclazz,StringmethodName,Class[]parameterTypes,Object[]parameters){
Objectresult=null;
try{
Methodmethod=null;
if(parameterTypes==null||parameterTypes.length==0){
method=clazz.getMethod(methodName);
if(Modifier.isStatic(method.getModifiers())){
callBack.before(method);
result=method.invoke(null);
callBack.after(method,result);
}else{
System.out.println("这不是一个静态方法");
}
}else{
method=clazz.getMethod(methodName,parameterTypes);
if(Modifier.isStatic(method.getModifiers())){
callBack.before(method);
result=method.invoke(null,parameters);
callBack.after(method,裂亮result);
}else{
System.out.println("这不是一个静态方法");
}
}
}catch(NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException
|InvocationTargetExceptione){
if()肆消宽{
System.out.println("没有这个方法");
}else{
System.out.println("calliserror!");
}
}
returnresult;
}
publicstaticvoidmain(String[]args){
CallBackcallBack=newCallBack(){
@Override
publicvoidbefore(Methodmethod){
if(method.getName().equals("test1")||method.getName().equals("test2")){
System.out.println(method.getName()+"方法在调用之前被拦桥大截,可以在这里切面编程");
}
}
@Override
publicvoidafter(Methodmethod,Objectresult){
if(method.getName().equals("test1")||method.getName().equals("test2")){
System.out.println(method.getName()+"方法调用以后被拦截,可以在这里切面编程");
System.out.println(method.getName()+"执行结果是:"+result);
System.out.println("-----------------------------------------");
}
}
};
=newAOPCallStaticMehtod(callBack);
AOPCallStaticMehtod.callMethod(Test.class,"test1",newClass[]{String.class},newObject[]{"ppppppppppp"});
AOPCallStaticMehtod.callMethod(Test.class,"test2",null,null);
}
}
classTest{
publicstaticvoidtest1(Stringaa){
System.out.println(aa);
}
publicstaticStringtest2(){
System.out.println("fffffffffffffffff");
return"test2result";
}
}
Ⅶ aspect java
aspect java是腊颂一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用轮裂郑来生成遵守Java字节编码规范的Class文件。
首先是几个概念:
aspect(层面)
pointcut(切入点)
advice(建议)
weave(织入)
LTW(加载期织入 load time weave)
按照aspectj的语法规则,一个aspect就是很多pointcut和advice的集合,也就是一个*.aj的文件。
一个pointcut就是对target class的切入点定义,类似Java class定义中的field。
一个advice就是对target class的行为改变,类似Java class中的method。
weave就是aspectj runtime库把aspect织入到target class的行为。
LTW就是指运行期间动态织入aspect的行为,它是相对静态织入行为(包括对源文件、二进制文件的修改)。
一般来讲,从运行速度上来说,源迹静态织入比动态织入要快些。因为LTW需要使用aspectj本身的classloader,它的效率要低于jdk的classloader,因此当需要load的class非常多时,就会很慢的。
举个例子来说明aspectj的使用:
scenario: Example工程需要使用一个类Line存在于第三方库Line.jar中,但是Line本身没有实现Serializable接口,并且其toString方法输出也不完善。因此这两点都需要修改。
Line的实现:
package bean; public class Line {undefined protected int x1 = 0; protected int x2 = 0; public int getX1(){undefined return x1; } public int getX2(){undefined return x2; } public void setLength(int newX, int newY){undefined setX1(newX); setX2(newY); } public void setX1(int newX) {undefined x1 = newX; } public void setX2(int newY) {undefined x2 = newY; } public String toString(){undefined return "(" + getX1() + ", " + getX2() + ")" ; } } Main entry : public class MyExample {undefined private Line line = null; public MyExample() {undefined line = new Line(); System.err.println("Line implement serializable interface : " + (line instanceof Serializable)); } public void showMe() {undefined System.out.println("Show all about me ..."); System.out.println(line.toString()); } public static void main(String[] args) {undefined MyExample demo = new MyExample(); // i want to change the action of show me, but i cannot get line source. // so i will trying load-time weaving demo.showMe(); } } output : Line implement serializable interface : true Show all about me ... (0, 0)Ⅷ Java中的@Aspect
这个面向切面编程,@Aspect 就是注解方式来注册切面的