术语:aop 面向切面,或面向方面
joint point 连接点
point cut 切入点
advice 通知
aspect 切面
target object 目标对象
weaving 织入
1.spring 对于aop 的支持
a.切面类在默认情况下可以不实现任何接口
b.但是,目标类(需要被代理的类)在默认情况下必须是实现了接口的类
c.如果不使用接口就必须引入cglib这个jar就可以解决了
d.默认情况是使用jdk的动态代理,只有你引入了cglib后,才会使用cglib的代理
e. <aop:aspectj-autoproxy proxy-target-class="true"/> 可以强制使实现了接口的目标类(需要被代理的类)使用cglib的动态代理
f.如果既有实现了接口的目标类(需要被代理的类),也有没有实现接口的代理类,那么没有使用接口的目标类(需要被代理的类)将会使用cglib的代理,实现了接口的类将会使用jdk的动态代理
例子: 首先是aspect类 首先采用注解的方式演示配置aop使用
package com.user.aop;
@Aspect
public class SecurityAop
{
/* @Pointcut("execution(* *.saveUser(..))")
private void checkMethod(){}
*/
@Before ("execution(* *.saveUser(..))")
private void checkSecurity(){
System.out.println("check sercurity==================");
}
}
接下来是接口
package com.user.manager;
public interface UserManager
{
void saveUser(String user);
String getUser();
void update();
}
接下来是实现类(目标类)(需要被代理的类)
package com.user.manager;
public class UserManagerImpl implements UserManager
{
public String getUser()
{
System.out.println("getuser---------------");
return null;
}
public void saveUser(String user)
{
System.out.println("save---------------");
}
public void update()
{
System.out.println("update---------------");
}
}
接下来是配置spring的配置文件
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 采用注解的方式配置aop -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> //必须有
<bean id="sercurityCheck" class="com.user.aop.SecurityAop"/>
<bean id="usermanager" class="com.user.manager.UserManagerImpl"/>
</beans>
测试类:
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager manager = (UserManager) factory.getBean("usermanager");
manager.saveUser("");
测试结果:
check sercurity=================
save---------------
2.采用静态配置的方式,改动只有几个地方,切面类就去掉注解即可
package com.user.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
public class SecurityAop2
{
private void checkSecurity(JoinPoint joinpoint){
Object[] objects = joinpoint.getArgs();
for(int i=0;i<objects.length;i++){
System.out.println(objects[i]);
}
System.out.println("check sercurity=================");
}
}
然后就是配置文件:
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 静态配置aop -->
<bean id="sercurityCheck" class="com.user.aop.SecurityAop2"/>
<bean id="usermanager" class="com.user.manager.UserManagerImpl"/>
<bean id="usermanager2" class="com.user.aop.UserManagerImpl2"/>
<aop:config>
<aop:aspect id="sercuritycheck" ref="sercurityCheck"> <!-- 指定切面类 -->
<aop:pointcut id="check" expression="execution(* com.user.*.*.*(..))"/><!-- 指定切入点在哪些方法上 这里指定的是这个包下面所有的方法-->
<aop:before method="checkSecurity" pointcut-ref="check"/> <!--通知, 必须关联一pointcut -->
</aop:aspect>
</aop:config>
</beans>
测试结果同上
3.Joinpot封装了代理方法以及方法的参数,我们可以在切面类中的切入方法中使用
这个是切面类中的方法
private void checkSecurity(JoinPoint joinpoint){
Object[] objects = joinpoint.getArgs();
for(int i=0;i<objects.length;i++){
System.out.println(objects[i]);
}
System.out.println("check sercurity=====2222222222============");
}
测试:
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager manager = (UserManager) factory.getBean("usermanager");
UserManager manager2 = (UserManager) factory.getBean("usermanager2");
manager2.saveUser("jianglh");
结果
jianglh //首先会拿到参数,拿到代理方法的方式:joinpoint.getSignature().getName();
check sercurity=====2222222222============
seave user 22222222222
----------------------------到这里呢,aop的使用就结束了-----------------------------