本文参考了royzhou1985 的博文,在此感谢他无私的分享。
一 什么是aop?
我的理解,aop就是让我们专心做我们最关心的功能,而把其他很多类都需要的公共的功能分离出来,从而大大提高了我们来发的效率,也方便以后的维护和拓展。比如说,你现在有一个普通用户类,用户里有采购商品,收藏商品,发表评论等业务功能,另外还有一个会员类,可能会有更多其他的功能,但他们都需要先登录,才能享有这些功能,所以登录这个功能就不是我们最为关心的,可能我们很多类的方法里都需要先实现这个功能。所以,aop就的作用就是帮我们把登录这个功能分离出去,让我们将更多的精力放到其他的功能实现中去。
二 aop的好处?
前面已经谈过了。
三 aop的实现方式?
aop主要有两种实现方式:jdk的动态代理和cglib代理。
动态代理,通俗的说,就是在代码里,只定义接口,然后再执行的过程中,将具体的目标对象织如到接口中。好比,你去装一台电脑,只需在电脑类里定义一个cpu接口,那么在具体的安装过程中,电脑类会动态的根据用户的需要织入具体的cpu,可能是amd的,可能是intel的。
jdk的动态代理,需要我们的目标对象所在类去实现接口。然后通过jdk里的反射机制去实现动态代理。
cglib代理,目标对象所在类不用去实现接口。它实现代理时用的是net.sf.cglib.
proxy.Enhancer这样一个类。
四 Spring aop相关概念。
在用Spring做aop前,有些基本概念是需要理解的。
Spring主要通过代理来实现AOP
下面是AOP的一些基本概念:
切面(Aspect):对横切关注点的抽象(类似类对对象的抽象)
连接点(JoinPoint):被拦截到的点,泛指方法
切入点(CutPoint):对哪些连接点进行拦截的定义
通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后)
引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。
目标对象(Target Object): 包含连接点的对象。也被称作 被通知或被代理对象。
AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时 完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样, 在运行时完成织入。
五 Spring aop的实现步骤。
Spring aop有两种实现方式,注释方式和xml配置方式。
对于注释方式,必须引入三个jar包:
aspectjweaver.jar
aspectjrt.jar
cglib.jar
首先写一个接口,一个任务目标所在类,然后再写一个带注释的通知,最后在spring的配置文件里配置就可以了。
对于xml配置方式,不需要导包,写通知类时也不用写注释。
六 用Spring aop实现一个简单的权限管理
我用的是xml配置方式实现的。
编写接口和实现类
java代码:
编写通知类:
java代码:
配置spring配置文件:
java代码:
编写测试类:
测试结果:
一 什么是aop?
我的理解,aop就是让我们专心做我们最关心的功能,而把其他很多类都需要的公共的功能分离出来,从而大大提高了我们来发的效率,也方便以后的维护和拓展。比如说,你现在有一个普通用户类,用户里有采购商品,收藏商品,发表评论等业务功能,另外还有一个会员类,可能会有更多其他的功能,但他们都需要先登录,才能享有这些功能,所以登录这个功能就不是我们最为关心的,可能我们很多类的方法里都需要先实现这个功能。所以,aop就的作用就是帮我们把登录这个功能分离出去,让我们将更多的精力放到其他的功能实现中去。
二 aop的好处?
前面已经谈过了。
三 aop的实现方式?
aop主要有两种实现方式:jdk的动态代理和cglib代理。
动态代理,通俗的说,就是在代码里,只定义接口,然后再执行的过程中,将具体的目标对象织如到接口中。好比,你去装一台电脑,只需在电脑类里定义一个cpu接口,那么在具体的安装过程中,电脑类会动态的根据用户的需要织入具体的cpu,可能是amd的,可能是intel的。
jdk的动态代理,需要我们的目标对象所在类去实现接口。然后通过jdk里的反射机制去实现动态代理。
cglib代理,目标对象所在类不用去实现接口。它实现代理时用的是net.sf.cglib.
proxy.Enhancer这样一个类。
四 Spring aop相关概念。
在用Spring做aop前,有些基本概念是需要理解的。
Spring主要通过代理来实现AOP
下面是AOP的一些基本概念:
切面(Aspect):对横切关注点的抽象(类似类对对象的抽象)
连接点(JoinPoint):被拦截到的点,泛指方法
切入点(CutPoint):对哪些连接点进行拦截的定义
通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后)
引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。
目标对象(Target Object): 包含连接点的对象。也被称作 被通知或被代理对象。
AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时 完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样, 在运行时完成织入。
五 Spring aop的实现步骤。
Spring aop有两种实现方式,注释方式和xml配置方式。
对于注释方式,必须引入三个jar包:
aspectjweaver.jar
aspectjrt.jar
cglib.jar
首先写一个接口,一个任务目标所在类,然后再写一个带注释的通知,最后在spring的配置文件里配置就可以了。
对于xml配置方式,不需要导包,写通知类时也不用写注释。
六 用Spring aop实现一个简单的权限管理
我用的是xml配置方式实现的。
编写接口和实现类
java代码:
- package com.hjy.SpringAopDemo.beans;
- public interface Loginer {
- public void login(String name,String pw);
- }
- package com.hjy.SpringAopDemo.beans;
- public class LoginerImpl implements Loginer {
- private String name;
- private String pw;
- public void login(String name,String pw) {
- this.name=name;
- this.pw=pw;
- System.out.println("用户:" + name + "登录成功!");
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getPw() {
- return pw;
- }
- public void setPw(String pw) {
- this.pw = pw;
- }
- }
package com.hjy.SpringAopDemo.beans;
public interface Loginer {
public void login(String name,String pw);
}
package com.hjy.SpringAopDemo.beans;
public class LoginerImpl implements Loginer {
private String name;
private String pw;
public void login(String name,String pw) {
this.name=name;
this.pw=pw;
System.out.println("用户:" + name + "登录成功!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPw() {
return pw;
}
public void setPw(String pw) {
this.pw = pw;
}
}
编写通知类:
java代码:
- package com.hjy.SpringAopDemo.advisor;
- import org.aopalliance.intercept.MethodInterceptor;
- import org.aopalliance.intercept.MethodInvocation;
- public class MyaroudAdvice implements MethodInterceptor {
- public Object invoke(MethodInvocation arg0) throws Throwable {
- System.out.println("开始登陆");
- if (arg0.getArguments()[1].equals("841026")) {
- System.out.println("欢迎" + arg0.getArguments()[0] + "您回来");
- return arg0.proceed();
- } else {
- System.out.println("对不起,您的密码错误,登录失败!");
- return null;
- }
- }
- }
package com.hjy.SpringAopDemo.advisor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyaroudAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("开始登陆");
if (arg0.getArguments()[1].equals("841026")) {
System.out.println("欢迎" + arg0.getArguments()[0] + "您回来");
return arg0.proceed();
} else {
System.out.println("对不起,您的密码错误,登录失败!");
return null;
}
}
}
配置spring配置文件:
java代码:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
- <bean id="LoginerImpl"
- class="com.hjy.SpringAopDemo.beans.LoginerImpl">
- </bean>
- <bean id="MyaroudAdvice"
- class="com.hjy.SpringAopDemo.advisor.MyaroudAdvice">
- </bean>
- <bean id="Login"
- class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="proxyInterfaces">
- <value>com.hjy.SpringAopDemo.beans.Loginer</value>
- </property>
- <property name="target">
- <ref local="LoginerImpl" />
- </property>
- <property name="interceptorNames">
- <list>
- <value>MyaroudAdvice</value>
- </list>
- </property>
- </bean>
- </beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="LoginerImpl"
class="com.hjy.SpringAopDemo.beans.LoginerImpl">
</bean>
<bean id="MyaroudAdvice"
class="com.hjy.SpringAopDemo.advisor.MyaroudAdvice">
</bean>
<bean id="Login"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.hjy.SpringAopDemo.beans.Loginer</value>
</property>
<property name="target">
<ref local="LoginerImpl" />
</property>
<property name="interceptorNames">
<list>
<value>MyaroudAdvice</value>
</list>
</property>
</bean>
</beans>
编写测试类:
- package com.hjy.SpringAopDemo.test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.hjy.SpringAopDemo.beans.Loginer;
- import com.hjy.SpringAopDemo.beans.LoginerImpl;
- public class Test {
- public static void main(String[] args) {
- ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
- Loginer loginer=(Loginer)ac.getBean("Login");
- loginer.login("张三","841000");
- loginer.login("李四","841026");
- }
- }
package com.hjy.SpringAopDemo.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hjy.SpringAopDemo.beans.Loginer;
import com.hjy.SpringAopDemo.beans.LoginerImpl;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Loginer loginer=(Loginer)ac.getBean("Login");
loginer.login("张三","841000");
loginer.login("李四","841026");
}
}
测试结果:
- 开始登陆
- 对不起,您的密码错误,登录失败!
- 开始登陆
- 欢迎李四您回来
- 用户:李四登录成功!