搭建Spring开发环境
有关Spring开发环境的搭建,请参考:http://www.leonwish.com/archives/79
撰写第一个Spring程序,理解SpringIOC工厂机制
撰写第二个Spring程序前,需要首先理解SpringIOC机制,请参考:http://www.leonwish.com/archives/81
撰写第二个Spring程序
第一步:在Maven的pom.xml中添加AOP依赖,代码如下:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
第二步:确定目标类,编写核心功能(也可以理解为这是当前系统已经有的功能)
service包下新建UserService接口
package com.royotech.service;
public interface UserService {
public boolean login(String username, String password);
}
service.impl子包下新建UserServiceImpl类,实现UserService接口。
package com.royotech.service.impl;
import com.royotech.service.UserService;
public class UserServiceImpl implements UserService{
@Override
public boolean login(String username, String password) {
System.out.println("我是核心功能:我登陆成功了!我的名字:"+username+",我的密码:"+password);
return true;
}
}
第三步:编写新功能类。
在aop包下新建MyAdvice类,作为新功能。
package com.royotech.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("我是织入功能:开始统计啦!");
invocation.proceed();//执行被切入类(目标类)中的既有方法的方法体。
System.out.println("我是织入功能:统计结束啦!");
return true;
}
}
第四步:编写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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 1. 配置目标类 -->
<bean id="userServiceImpl" class="com.royotech.service.impl.UserServiceImpl"></bean>
<!-- 2. 配置额外功能类 -->
<bean id="myAdvice" class="com.royotech.aop.MyAdvice"></bean>
<aop:config>
<!-- 3. 确定切入点 -->
<aop:pointcut id="pcut" expression="execution(boolean com.royotech.service.impl.UserServiceImpl.login(java.lang.String,java.lang.String))"></aop:pointcut>
<!-- 4. 将额外功能织入切入点 -->
<aop:advisor advice-ref="myAdvice" pointcut-ref="pcut"/>
</aop:config>
</beans>
注意,xml头部需要添加aop相关内容。
第五步:大功告成,测试一下
在view包下新建PersonSpringAOP.java
package com.royotech.view;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.royotech.service.UserService;
public class PersonSpringAOP {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//这里面用接口,不能用UserServiceImpl类
//因为本质上讲动态代理自动生成的隐藏对象应该与目标类实现同样的接口
//因此动态代理对象和目标类不是同类对象,只是继承了相同的方法。
UserService userService = (UserService)ac.getBean("userServiceImpl");
userService.login("ROYOTECH", "123123");
}
}
运行一下,看看结果,欧耶!!!
理解为什么使用SpringAOP
AOP(Aspect Oriented Programming)面向切面编程。底层基于动态代理机制实现。简单的来说就是如果系统需要增加某额外功能的时候,在不改变原有代码的情况下,可以通过AOP机制将新的功能织入到程序的切入点(切入点可以精确到方法)上。这是非常好的一种解耦合的机制。作用类似于JAVA拦截器和过滤器。
我能想到的典型应用场景有两个:
客户之前委托第三方开发了某JAVA系统,现在委托给你做新功能添加。最稳妥的方式是以AOP的形式将新功能织入到现有系统中。这样不会影响之前的代码结构,后期也便于单独维护自己的代码。
假如我们想统计下当前所有Service层函数的执行时间,以便优化代码。不可能给每个函数单独增加统计时间的代码。最好的方法是通过AOP,将统计代码织入到函数切入点中。