術語: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的使用就結束了-----------------------------