Spring项目二-AOP

Spring AOP概念:

AOP:Aspect Oriented Program ---------面向切面编程。

  • 功能:核心业务功能(如登录,增删数据等)和周边功能(日志等),周边功能在Spring的面向切面编程的AOP思想里,被定义为切面。
  • 核心业务和切面功能分别独立开发,然后有选择性的把切面功能和核心业务功能“编织”在一起,这就是AOP。

AOP项目

- 项目设计

核心功能:ProductService和ProductService1
辅助功能:日志输出,性能统计

- 项目开始

1,**就像一般的Java类,编写核心功能类。

public class ProductService {
	public void doSomeService(){
		System.out.println("doSomeService");
	}
	public void doCheck(){
		System.out.println("Do check");
	}
}

2,准备日志和性能统计切面**
例如日志切面:

示例代码如下:

public class LoggerAspect { 

	public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("start log:" + joinPoint.getSignature().getName());
		
		Object object = joinPoint.proceed();
       //与某个核心功能编织后,用于执行性核心功能
       //所以,此日志切面功能是:在调用核心功能前后分别打印日志文件函数名字

		System.out.println("end log:" + joinPoint.getSignature().getName());
		return object;
	}
}

3,编写applicationContext.xml文件

  • 声明业务对象(按照一般类对象声明)
<bean name="s" class="com.moon.service.ProductService">
</bean>
  • 声明日志切面(注意是bean id=xx,且不需要结尾)
<!-- 控制反转   切面类 -->
    <bean id="loggerAspect" class="com.moon.aspect.LoggerAspect"/>
    <!-- 控制反转    性能统计的切面类 -->
    <bean id="performerAspect" class="com.moon.aspect.PerformerAspect"/>
  • 在aop:config和</aop:config>中指定核心功能和切面业务,并把他们编织起来
    (1)设置核心功能
 <aop:config>
 <!--不同的切入点要分别写在不同的aop:config里面-->
        <!-- 设置切入点(核心功能)的作用对象和id -->
        <aop:pointcut id="Cutpoint"
                         expression="execution(* com.moon.service.ProductService.*(..)) "/>
                      //执行所有的核心功能ProductService类里面的所有函数
       //指定辅助功能
    </aop:config>

execution(* com.moon.service.ProductService.*(…))函数:
# *表示返回任意类型
# com.moon.service.ProductService.*是指以包名com.moon.service下类 ProductService的任意方法
# (…)表示任意数量和类型

(2)指定辅助功能
一个辅助功能与多个核心功能编织,切面aspect id要不同,但是注入同样对象

 <!-- 设置切面的id,注入对象-->
      <aop:aspect id="logAspect" ref="loggerAspect">

      <!--该切面中的log方法会被以环绕“around”方式放置于Cutpoint切入点  -->
            <aop:around pointcut-ref="Cutpoint" method="log"/>
            <aop:around pointcut-ref="Cutpoint" method="log1"/>
        </aop:aspect>
        
 <!--该切面中的spend方法会被以环绕“around”方式放置于Cutpoint切入点  -->
        <aop:aspect id="performAspect" ref="performerAspect">
            <aop:around pointcut-ref="Cutpoint" method="spend"/>
        </aop:aspect>

<aop:config>
        <aop:pointcut id="cutpoint1" expression="execution(* com.moon.service.ProductService1.*(..)) "/>
        <aop:aspect id="logAspect1" ref="loggerAspect">
            <aop:around pointcut-ref="cutpoint1" method="log"/>
            <aop:around pointcut-ref="cutpoint1" method="log1"/>
        </aop:aspect>
    </aop:config>

4,编写测试类
只需定义核心功能的对象,并调用其方法即可,被调用的方法将会被切面类中的方法按照顺序环绕。

 ProductService s = (ProductService) context.getBean("s");
        s.doSomeService();
        s.doCheck();

具体代码

ProductService.java

package com.moon.service;

public class ProductService {
	public void doSomeService(){
		System.out.println("doSomeService");
	}
	public void doCheck(){
		System.out.println("Do check");
	}
}

ProductService1.java

package com.moon.service;

public class ProductService1 {
    public void show(){
        System.out.println("this is another a service");
    }
}

LoggerAspect.java

package com.moon.aspect;
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggerAspect {
	public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("start log:" + joinPoint.getSignature().getName());
		Object object = joinPoint.proceed();
		System.out.println("end log:" + joinPoint.getSignature().getName());
		return object;
	}
	public Object log1(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("my log0:" + joinPoint.getSignature().getName());
		Object object = joinPoint.proceed();
		System.out.println("my log1:" + joinPoint.getSignature().getName());
		return object;
	}
}

PerformerAspect.java

package com.moon.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import java.util.Date;

public class PerformerAspect {
        //环绕式切入
        public Object spend(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            long start = System.currentTimeMillis();
            System.out.println("开始于" + new Date(start));
            Object object = proceedingJoinPoint.proceed();
            long end = System.currentTimeMillis();
            System.out.println("结束于" + new Date(end));
            return object;
        }
    }

TestSpring.java

package com.moon.test;

import com.moon.service.ProductService;
import com.moon.service.ProductService1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "applicationContext.xml" });
        ProductService s = (ProductService) context.getBean("s");
        s.doSomeService();
        s.doCheck();
        ProductService1 s1 = (ProductService1) context.getBean("s1");
        s1.show();

    }
}

applicationContext.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-3.0.xsd
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
    <bean name="s" class="com.moon.service.ProductService">
    </bean>
    <bean name="s1" class="com.moon.service.ProductService1">
    </bean>
    <!-- 控制反转   切面类 -->
    <bean id="loggerAspect" class="com.moon.aspect.LoggerAspect"/>
    <!-- 控制反转    性能统计的切面类 -->
    <bean id="performerAspect" class="com.moon.aspect.PerformerAspect"/>

    <aop:config>
        <!-- 设置切入点的作用对象和id -->
        <aop:pointcut id="Cutpoint"
                      expression=
                              "execution(* com.moon.service.ProductService.*(..)) "/>
        <!-- 设置切面的id,以及该切面中的log方法会被以环绕“around”方式放置于loggerCutpoint切入点  -->
        <aop:aspect id="logAspect" ref="loggerAspect">
            <aop:around pointcut-ref="Cutpoint" method="log"/>
            <aop:around pointcut-ref="Cutpoint" method="log1"/>
        </aop:aspect>
        <!-- bean时一个id,aop时一个id -->
        <aop:aspect id="performAspect" ref="performerAspect">
            <aop:around pointcut-ref="Cutpoint" method="spend"/>
        </aop:aspect>

    </aop:config>
    <aop:config>
        <aop:pointcut id="cutpoint1" expression="execution(* com.moon.service.ProductService1.*(..)) "/>
        <aop:aspect id="logAspect1" ref="loggerAspect">
            <aop:around pointcut-ref="cutpoint1" method="log"/>
            <aop:around pointcut-ref="cutpoint1" method="log1"/>
        </aop:aspect>
    </aop:config>

</beans>

运行结果:
一个一个切面可以编织到多个切入点(核心功能),可以通过调用核心功能方法来实现编织,但是一个切面编织到多个切入点需要在aop:aspect里面设置不同的切面id。
多个切面可以与一个切入点编织,只要在一个切入点设置里面分别声明切面id以及其切入点和切面方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值