AOP入门

AOP简介:java

  面向切面的编程(也叫面向方面编程):Aspect Oriented Programming(AOP),是软件开发中的一个热点,也是 Spring框架中的一个重要内容。利用AOP能够对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度下降,提升程序的可重用性,AOP是OOP编程的延续。spring

与OOP的区别:express

   面向对象编程主要用于为同一对象层次的公用行为建模。它的弱点是将公共行为应用于多个无关对象模型之间。而这偏偏是面向方面编程适合的地方。有了 AOP,咱们能够定义交叉的关系,并将这些关系应用于跨模块的、彼此不一样的对象模型。AOP 同时还可让咱们层次化功能性而不是嵌入功能性,从而使得代码有更好的可读性和易于维护。它会和面向对象编程合做得很好。编程


 举个例子:app


学生的service类框架

public class StudentServiceImpl implements IStudentService{

	@Override
	public void addStudent(String name) {
		// TODO Auto-generated method stub
		System.out.println("姓名:"+name);
	}

}



 如今有个需求:在添加方法的逻辑中,添加以前输出日志,添加完成以后输出添加成功日志,最简单的方法是:ide

public class StudentServiceImpl implements IStudentService{

	@Override
	public void addStudent(String name) {
		// TODO Auto-generated method stub
		
		//输出日志逻辑代码
		
		System.out.println("姓名:"+name);
		
		//添加成功日志代码
	}

}


如今咱们又有别的Service 类也须要一样的需求。须要修改的类足足有100个(开个玩笑) ,不可能一个个去修改,Service类,并且俩个输出日志的代码在其余Service类中是同样的,若是一直复制粘贴对代码没有作到可复用性。测试

这个时候AOP就派上用处了。spa


以Spring框架中为例:代理

 spring.xml中AOP配置:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">


	<context:component-scan base-package="com.younchen.*" />


	<bean id="StudentImpl" class="com.younchen.aop.StudentImpl" />
        <bean id="DaliyLog" class="com.younchen.aop.DaliyLog"/> 
        <bean id="Log" class="com.younchen.aop.Log"/>

	<aop:config>
		<!-- expression 括号 第一个 星号表示 全部返回值类型,第二个星号表示全部类,第三个星号表示全部的方法,括号俩点表示方法参数 -->
		<aop:pointcut expression="execution(* com.younchen.aop.*.*(..))"
				id="target" />
		<aop:aspect id="Logger" ref="Log">
			<aop:before method="beforeAdd" pointcut-ref="target" />
			<aop:after method="afterAdd" pointcut-ref="target" />
		</aop:aspect>
	</aop:config>
</beans>

 在config 标签中的第一个标签pointcut是切入点, expression是表达式, 看下括号中的第一个*号,意思是针对于全部的返回类型 ,紧接着是类所在的包名,以后的俩个星号分别表明类名和方法名 ,后面的括号中俩个点表明全部的参数。该标签的做用是声明在执行com.younchen.aop这个包下的全部类的全部方法时执行咱们要切入的方法 。

 aspect标签是切面也就是咱们要切入的方法  ref指定咱们的切入方法的类,该标签中的子标签 before method的做用是expression表达式中指定的类的方法执行前执行, after method是以后执行。 pointcut-ref 是指定切入点,除了引用的切入点(表达式指定的范围外) 该切面是不执行的。

未给出的完整代码:

Log类:

package com.younchen.aop;

public class Log {

	
	public void beforeAdd(){
		System.out.println("准备添加数据");
	}
	
	public void afterAdd(){
		System.out.println("添加完成");
	}
}

SpringUtil类:

public class SpringUtil {

		private static ApplicationContext context = null;
		
		public static ApplicationContext getApplicationContext() {
			if (context == null) {
				context = new ClassPathXmlApplicationContext("spring.xml");
			}
			return context;
		}

		public static ApplicationContext getApplicationContext(String path) {
			return new ClassPathXmlApplicationContext(path);
		}

		public static ApplicationContext getAnnotationConfigApplicationContext(String basePackages) {
			return new AnnotationConfigApplicationContext(basePackages);
		}
}

其余service类:

public class DaliyLog {

	public void addLog(){
		System.out.println("添加每日日志");
	}
}



测试类:

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	  ApplicationContext applicationContext=(ApplicationContext) SpringUtil.getApplicationContext("springaop.xml");
	  IStudent studentService=(IStudent) applicationContext.getBean("StudentImpl");
	  DaliyLog daliyLog=(DaliyLog) applicationContext.getBean("DaliyLog");
	  
	  studentService.addStudent("麦克米兰");
	  System.out.println("-----------------------------------------------------------");
	  daliyLog.addLog();
	}
}

执行结果:

准备添加数据
姓名:麦克米兰
添加完成
-----------------------------------------------------------
准备添加数据
添加每日日志
添加完成


  以上是简单一个例子,AOP的原理实际上是动态代理。 切面是被动态代理的类, 在被动态代理时,产生一个新的类,在这个类中除了执行被代理的方法外,还注入了切面的方法。

欢迎指正。

相关文章
相关标签/搜索