您的位置:首页 > 编程语言 > Java开发

Spring总结(五)--Spring中使用AOP三种方式

2017-03-12 15:01 435 查看
第一种实现的方式:通过Spring的API实现AOP。

第一步:

public interface UserService {

public void add();

public void update(int a);

public void delete();

public void search();

}


第二步:

public class UserServiceImpl implements UserService {


@Override

public void add() {

System.out.println("增加用户");

}


@Override

public void update(int a) {

System.out.println("修改用户");

}


@Override

public void delete() {

System.out.println("删除用户");

}


@Override

public void search() {

System.out.println("查询用户");

}


第三步:实现MethodBeforeAdvice的接口,Spring框架当中为我们提供了很多中通知。

public class Log implements MethodBeforeAdvice{

/**

* @param method 被调用方法对象

* @param args 被调用的方法的参数

* @param target 被调用的方法的目标对象

* */

@Override

public void before(Method method, Object[] args, Object target)

throws Throwable {

System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行");

}

}


第四步:配置beans.xml文件

<?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:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop[/code] 
http://www.springframework.org/schema/aop/spring-aop.xsd">[/code] 
<bean id="userService" class="com.spring.service.impl.UserServiceImpl"/>

<!--  这个切面也要配置成bean-->

<bean id="log" class="com.spring.advice.Log"/>

<aop:config>

<!--切入点,需要告诉方法在什么去执行

expression="execution(* com.spring.service.impl.*.*(..))"

第一个* 表示所有的返回值,然后就是包名

第二个*表示所有的类对象

第三个*表示类对象所有的方法

第四个*表示所有方法下面的带参数的方法或者是不带参数的方法

-->

<aop:pointcut expression="execution(* com.spring.service.impl.*.*(..))" id="pointcut"/>

<!--  在所有的方法中都切入前置通知-->

<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>

</aop:config>

</beans>


第五步:测试:

package com.spring.test;


import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;


import com.spring.service.UserService;


public class Test {

public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

UserService userService = (UserService)ac.getBean("userService");

userService.update(2);

userService.add();

}

}


运行结果:

三月 12, 2017 2:22:44 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@439f5b3d: startup date [Sun Mar 12 14:22:44 GMT+08:00 2017]; root of context hierarchy

三月 12, 2017 2:22:44 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [beans.xml]

com.spring.service.impl.UserServiceImpl的update方法被执行

修改用户

com.spring.service.impl.UserServiceImpl的add方法被执行

增加用户


故前置通知可以在spring当中被执行,接下可以完善通知;

public class AfterLog implements AfterReturningAdvice{

/**

* 目标方法执行后执行的通知

* returnValue--返回值

* method 被调用的方法对象

* args 被调用的方法对象的参数

* target 被调用的方法对象的目标对象

* */

@Override

public void afterReturning(Object returnValue, Method method,

Object[] args, Object target) throws Throwable {

System.out.println(target.getClass().getName()+"的"+method.getName()+"被成功执行,返回值是:"+returnValue);

}

}



import java.lang.reflect.Method;


import org.springframework.aop.ThrowsAdvice;


public class ExceptionLog implements ThrowsAdvice {

public void afterThrowing(Method method,Exception ex) throws Throwable {

}


}


重新配置:

<!--  这个切面也要配置成bean-->

<bean id="log" class="com.spring.advice.Log"/>

<bean id="afterLog" class="com.spring.advice.AfterLog"></bean>

<aop:config>

<!--切入点,需要告诉方法在什么去执行

expression="execution(* com.spring.service.impl.*.*(..))"

第一个* 表示所有的返回值,然后就是包名

第二个*表示所有的类对象

第三个*表示类对象所有的方法

第四个*表示所有方法下面的带参数的方法或者是不带参数的方法

-->

<aop:pointcut expression="execution(* com.spring.service.impl.*.*(..))" id="pointcut"/>

<!--  在所有的方法中都切入前置通知-->

<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>

<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>

</aop:config>


测试运行结果:

三月 12, 2017 2:28:19 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@439f5b3d: startup date [Sun Mar 12 14:28:19 GMT+08:00 2017]; root of context hierarchy

三月 12, 2017 2:28:19 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [beans.xml]

com.spring.service.impl.UserServiceImpl的update方法被执行

修改用户

com.spring.service.impl.UserServiceImpl的update被成功执行,返回值是:null

com.spring.service.impl.UserServiceImpl的add方法被执行

增加用户

com.spring.service.impl.UserServiceImpl的add被成功执行,返回值是:null


总结:AOP的重要性,非常重要 

Spring的AOP就是将公共的业务(如日志,安全等)和业务类结合。当执行业务的时候将会把公共业务加进来。实现公共业务的重复利用。我们自己的业务就会变得更加的纯粹,我们就可以关注我们的自己的业务,本质就是动态代理。

第二种方式:自定义类来实现AOP,不实现spring的自带的通知

第一步:重新通知:

public class Log {


public void before(){

System.out.println("方法执行前");

}

public void after(){

System.out.println("方法执行后");

}

}


第二步:重新写配置文件

<?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:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop[/code] 
http://www.springframework.org/schema/aop/spring-aop.xsd">[/code] 
<bean id="userService" class="com.spring.service.impl.UserServiceImpl"/>

<!--  这个切面也要配置成bean-->

<bean id="log" class="com.spring.advice.Log"/>

<aop:config>

<!--切入点,需要告诉方法在什么去执行

expression="execution(* com.spring.service.impl.*.*(..))"

第一个* 表示所有的返回值,然后就是包名

第二个*表示所有的类对象

第三个*表示类对象所有的方法

第四个*表示所有方法下面的带参数的方法或者是不带参数的方法

-->

<aop:aspect ref="log">

  <aop:pointcut expression="execution(* com.spring.service.impl.*.*(..))" id="pointcut"/>

  <aop:before method="before" pointcut-ref="pointcut"/>

  <aop:after method="after" pointcut-ref="pointcut"/>

  </aop:aspect>

</aop:config>

</beans>


第三种方式:通过注解实现AOP

第一步:修改log

package com.spring.advice;


import java.lang.reflect.Method;


import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.aop.MethodBeforeAdvice;


@Aspect

public class Log {


@Before("execution(* com.spring.service.impl.*.*(..))")

public void before(){

System.out.println("方法执行前");

}

@After("execution(* com.spring.service.impl.*.*(..))")

public void after(){

System.out.println("方法执行后");

}

@Around("execution(* com.spring.service.impl.*.*(..))")

public Object around(ProceedingJoinPoint jp) throws Throwable{


System.out.println("环绕前");

System.out.println("方法"+jp.getSignature());

Object result=jp.proceed();

System.out.println("环绕后");

return result;

}

}


第二步:修改beans.xml

<?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:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/aop[/code] 
http://www.springframework.org/schema/aop/spring-aop.xsd">[/code] 
<bean id="userService" class="com.spring.service.impl.UserServiceImpl"/>

<!--  这个切面也要配置成bean-->

<bean id="log" class="com.spring.advice.Log"/>

<aop:aspectj-autoproxy/>

</beans>


第三步:运行:

三月 12, 2017 3:00:02 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@439f5b3d: startup date [Sun Mar 12 15:00:02 GMT+08:00 2017]; root of context hierarchy

三月 12, 2017 3:00:02 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

信息: Loading XML bean definitions from class path resource [beans.xml]

环绕前

方法void com.spring.service.UserService.update(int)

方法执行前

修改用户

环绕后

方法执行后
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  api aop spring springAOP