知识点1:After和Before
public class LubanAspectJPre {
@Pointcut("within(com.luban.dao.IndexDao)")//切点
public void pointCutWithin(){
}
@Before("pointCutWithin()")//advice通知
public void before(JoinPoint joinPoint){
System.out.println("before");
}
@After("pointCutWithin()")
public void after(JoinPoint joinPoint){
System.out.println("before");
}
}
知识点2:环绕通知
环绕的要加:ProceedingJoinPoint处理我们的连接点。
代码:
@Around("pointCutWithin()")
public void around(ProceedingJoinPoint pjp)throws Throwable{
System.out.println("around");
}
Dao dao = (Dao)annotationConfigApplicationContext.getBean("indexDao");
System.out.println(dao instanceof IndexDao);
dao.qyery1("a");
执行dao.qyery1("a");方法的时候肯定会获得我们的连接点。被监控到。
SpringAOP找到目标对象对象的所有的方法,依次去完成增强。
ProceedingJoinPoint指的是正在增强的一个方法,表示当前的一个连接点。
JoinPoint是连接点,通过这个对象可以得到其所在得目标对象,代理对象,参数等,方法得签名,方法得返回类型。
----
假设我们描述一个人,则可知,属性方法。我们来描述一个连接点。
我们看下ProceedingJoinPoint继承的类的这个方法:
看注释:返回当前执行的对象。
dao.query():这个方法的当前的执行的对象是indexDao,这个是错的,当前对象应该是代理的对象。
这个拿到的是目标对象。
测试:
@Before("pointCutWithin()")
public void before(JoinPoint joinPoint){
System.out.println("before");
System.out.println(joinPoint.getThis());
System.out.println(joinPoint.getTarget());
}
打印:
@Configuration
//其中true是cgLib
@EnableAspectJAutoProxy(proxyTargetClass = false)
//@ComponentScan(value="com.luba.dao2")
@ComponentScan({"com.luban"})
public class AppConfig {
}
得到这个结果的前提是false即使用JDK的动态代理。
JOINPOINT:连接点的信息,目标对象,代理对象。
------------------------------------------------------------------------------------------------------------------------------
如何完成环绕
一个问题:我们的连接点是没有办法去执行的。
环绕:ProceedingJoinPoint 是增强的JoinPoint,JoinPoint不然无法执行连接点。
@Component
@Aspect
public class AspectAround {
@Pointcut("within(com.luban.dao.IndexDao)")
public void pointCutWithin(){
}
@Around("pointCutWithin()")
//ProceedingJoinPoint就是正在增强的连接点
public void after(ProceedingJoinPoint pjp){
System.out.println("aroundbdfore");
try {
pjp.proceed();//调用目标方法,必须加这个达到环绕的
} catch (Throwable throwable) {
throwable.printStackTrace();
}
//属于哪个类
System.out.println("aroundafter");
}
before 目标方法 after
--
环绕通知的作用:改变参数。
这个重载的方法,可以传各种各样奇怪的参数的。
还有这个方法:
@Around("pointCutWithin()")
public void around(ProceedingJoinPoint pjp)throws Throwable{
System.out.println("aroundbefore");
Object[] object = pjp.getArgs();
if(object!=null&&object.length>0){
for(int i=0;i<object.length;i++){
object[i]+="fdy";
}
}
pjp.proceed(object);//这个是调用目标方法
System.out.println("aroundafter");
}
用环绕通知一般是改变参数的。
------------------------------------------------------------------------
下一个知识点---------------------------------------------------------------------------------------------------------------------------------------------------
用的很少,先不看了用的时候再说吧:
代码:
:引入
使用的步骤:
1.声明
//找到鲁班下面的所有的类 引入Dao接口下面的IndexDao的实现
@DeclareParents(value="com.luban.dao.*+", defaultImpl=IndexDao.class)
public static Dao dao;
声明一个接口Dao,找到接口的实现IndexDao.class。
找到luban.dao下面的所有了,引入Dao接口的IndexDao实现。
实现后是这个样子的。
2.新建接口
3.Test方法验证
AnnotationConfigApplicationContext annotationConfigApplicationContext
= new AnnotationConfigApplicationContext(AppConfig.class);
Dao dao1 = (Dao)annotationConfigApplicationContext.getBean("orderDao");
dao1.qyery1("123");
System.out.println(dao1);
加上声明可以强转。
说明:https://blog.csdn.net/hardor/article/details/62427332
实现不是继承接口。
---------------------------------------------------------------------------------------------------------------------------------------------
下一个知识点:
Aspect提供很多中,但是spring只是支持的是perthis和pertarget。
aop是单例的。
代码:
看下结果:
了解就可以。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
知识点:
Before一般是指定切点的方法。
-----
新的内容:
@AspectJ语法切面就是类
xmld的就是标签:
------------------------------------------------------
代码:luban/aop4
代码1:luban/aop4