AOP:面向切面编程。实现业务与其他功能的解耦。
首先引入:Spring Framework相关包、commons-logging、aopalliance.jar包
AOP包含4中通知:前置通知、后置通知、环绕通知、抛出通知
创建IUser接口
package springproject.demo;
public interface IUser {
public void pringName() throws Exception ;
}
实现IUser接口
package springproject.demo;
public class User implements IUser{
@Override
public void pringName() throws Exception {
System.out.println("hello the world");
//throw new Exception("");
}
}
创建前置通知:
package springproject.demo;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class UserBefore implements MethodBeforeAdvice {
private void print() {
System.out.println("方法执行开始");
}
@Override
public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
print();
}
}
创建抛出通知:
package springproject.demo;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class UserThrow implements ThrowsAdvice {
public void afterThrowing(Method m, Object args, Object target,
Throwable subclass) {
System.out.println("方法运行出错了!");
}
}
package springproject.demo;
import org.springframework.aop.framework.ProxyFactory;
public class Main {
public static void main(String[] args) throws Exception {
testAOP();
}
private static void testAOP() throws Exception {
ProxyFactory factory = new ProxyFactory();
factory.addAdvice(new UserBefore());
factory.setTarget(new User());
User user = (User)factory.getProxy();
user.pringName();
}
}
2、使用Spring IOC以及ProxyFactoryBean
创建Bean.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-2.0.xsd">
<bean id="user1" class="springproject.demo.User">
</bean>
<bean id="user2" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="user1"></property>
<property name="interceptorNames" >
<list>
<value>myAspect</value>
</list>
</property>
</bean>
<bean id="myAspect" class="springproject.demo.UserBefore">
<!-- configure properties of aspect here as normal -->
</bean>
</beans>
访问:
package springproject.demo;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class Main {
public static void main(String[] args) throws Exception {
Resource resource = new FileSystemResource("bean.xml");
BeanFactory factory = new XmlBeanFactory(resource);
IUser bean = (IUser)factory.getBean("user2");
bean.pringName();
}
}
3、Spring中@Aspectj的使用
需要引入:aspectjrt以及aspectjweaver包
创建目标对象,普通的java类
package springproject.demo;
public class Person {
private String mName;
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
}
创建切面以及通知
package springproject.demo;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class NotVeryUsefulAspect {
@Pointcut("execution(* springproject.demo.Person.*(..))")
public void foundMonkey(){
}
@Before(value="foundMonkey()")
public void test() {
System.out.println("hello aspect");
}
@Before("execution(* springproject.demo.Person.*(..))")
public void print() {
System.out.println("原来是这样");
}
}
在类上应用@Aspect注解
@Pointcut定义切面。括号内为切面表达式,代表横切demo包下Person类的所有方法。foundMonkey为切面签名,返回值必须为void。
@Before前置通知,应用在方法上。
配置:
<?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-2.0.xsd">
<aop:aspectj-autoproxy />
<bean class="springproject.demo.NotVeryUsefulAspect" />
<bean id="person1" class="springproject.demo.Person">
<property name="name" value="xx"></property>
</bean>
</beans>
使用:
private static void testAspect() {
ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml");
Person person = (Person) context.getBean("person1");
person.getName();
}
在调用getName方法之前会先直线test和print方法。
注意:
以下代码是使用BeanFactory来获取Bean,但调用getName方法却不会执行test和print方法
Resource resource = new FileSystemResource("bean.xml");
BeanFactory factory = new XmlBeanFactory(resource);
Person mybean = (Person) factory.getBean("person1");
System.out.print(mybean.getName());