首先先写好一个JFinal的AOP,InjectorInterceptor.java。JFinal的AOP需要实现Interceptor的接口。并且重写intercept方法。
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class InjectorInterceptor implements Interceptor {
@Override
public void intercept(Invocation inv) {
// TODO Auto-generated method stub
System.out.println("InjectorInterceptor....");
inv.invoke();
}
}
然后在DemoConfig.java里配置拦截器的方法添加addGlobalServiceInterceptor的方法。
@Override
public void configInterceptor(Interceptors me) {
me.addGlobalServiceInterceptor(new InjectorInterceptor());
}
然后就可以添加service的类了。
package Service;
import com.jfinal.aop.Before;
import Interceptor.InjectorInterceptor;
public class service {
// @Before(InjectorInterceptor.class)
public void Intservice(){
System.out.println("Intservice...");
}
public void commond(){
System.out.println("commond...");
}
}
当然这里也可以加这个@Before注解,同时DemoConfig.java的拦截器方法不写addGlobalServiceInterceptor的方法,但这样的话这个拦截器就变成了一个普通拦截器。打印结果就会变成这样,下面那个commond方法上面就没有"InjectorInterceptor..."了。
InjectorInterceptor....
Intservice...
commond...
接下来写Controller。我这里写了一个IndexController.java类。
package demo;
import com.jfinal.aop.Before;
import com.jfinal.aop.Duang;
import com.jfinal.aop.Enhancer;
import com.jfinal.core.Controller;
import com.sun.xml.internal.bind.v2.runtime.output.Encoded;
import Interceptor.ClassInterceptor;
import Interceptor.InjectorInterceptor;
import Interceptor.MethodInterceptor;
import Service.service;
import Service.serviceImpl;
//@Before(ClassInterceptor.class)
public class IndexController extends Controller {
public void testService(){
System.out.println("========第一种方式===========");
service ser = Duang.duang(serviceImpl.class);
ser.Intservice();
ser.commond();
System.out.println("========第二种方式===========");
service ser1 = Enhancer.enhance(serviceImpl.class);
ser1.Intservice();
ser1.commond();
renderHtml("MyHtml.html");
}
}
这里说明一下。JFinal 3.0中Duang方法 实际上是同等于Enhancer的。
我这里新建了两个service对象是为了做比较。实际上这两个写法得出来的结果是一样的。
========第一种方式===========
InjectorInterceptor....
Intservice...
InjectorInterceptor....
commond...
========第二种方式===========
InjectorInterceptor....
Intservice...
InjectorInterceptor....
commond...
当然这个方法咱们还可以这样写。
public void testService(){
System.out.println("========第二种方式===========");
serviceImpl ser1 = Enhancer.enhance(serviceImpl.class,InjectorInterceptor.class);
ser1.Intservice();
ser1.commond();
renderHtml("MyHtml.html");
}
再Enhancer/Duang后面加了InjectorInterceptor.class的话等于从这里会调用一次拦截器。所以加了这个的话DemoConfig.java里拦截器方法可以不写。写了的话就是程序走到这个方法里会调用两次拦截器。
========第二种方式===========
InjectorInterceptor....
InjectorInterceptor....
Intservice...
InjectorInterceptor....
InjectorInterceptor....
commond...
===============
然后既然写到这里就顺便把@Before() AOP注解写下。
1.@Before()如果放在方法上面。代表对此方法的拦截。
package Interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class MethodInterceptor implements Interceptor{
@Override
public void intercept(Invocation inv) {
// TODO Auto-generated method stub
System.out.println("methodInterceptor.....");
inv.invoke();
}
}
@Before(MethodInterceptor.class)
public void testMethod(){
renderHtml("MyHtml.html");
}
打印结果:
methodInterceptor.....
2.@Before()如果放在类的上面。代表对整个类的拦截。优先级大于方法拦截。
package Interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class ClassInterceptor implements Interceptor {
@Override
public void intercept(Invocation inv) {
// TODO Auto-generated method stub
System.out.println("ClassInterceptor.....");
inv.invoke();
}
@Before(ClassInterceptor.class)
public class IndexController extends Controller {
打印结果:
ClassInterceptor.....
methodInterceptor.....
3.在DemoConfig.java的拦截器里加这个方法(注释掉的方法和那个add的方法是一样的效果)。
/**
* 配置全局拦截
*/
@Override
public void configInterceptor(Interceptors me) {
me.add(new GlobalInterceptor());
//me.addActionServiceInterceptor(new InjectorInterceptor());
}
然后写个拦截器。
package Interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class GlobalInterceptor implements Interceptor {
@Override
public void intercept(Invocation inv) {
// TODO Auto-generated method stub
System.out.println("GlobalInterceptor...");
inv.invoke();
}
}
这里添加的add方法代表这里加了一个全局拦截器。得出来的结果运行优先级是大于类拦截器和方法拦截器的。
GlobalInterceptor...
ClassInterceptor.....
methodInterceptor.....
================
然后还有个拦截器栈的概念。
我这里先写两个拦截器出来。
一个拦截器A,一个拦截器B。
package Interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class AInterceptor implements Interceptor {
@Override
public void intercept(Invocation inv) {
// TODO Auto-generated method stub
System.out.println("AInterceptor.....");
inv.invoke();
}
}
package Interceptor;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class BInterceptor implements Interceptor {
@Override
public void intercept(Invocation inv) {
// TODO Auto-generated method stub
System.out.println("BInterceptor.....");
inv.invoke();
}
}
然后写一个测试方法testMethodStack,同时给上注解@Before,这里注解里面要这样写。
@Before({AInterceptor.class,BInterceptor.class})
public void testMethodStack(){
renderHtml("MyHtml.html");
}
这样写代表程序走到这里时会先执行A拦截器,再执行B拦截器。执行顺序是从左到右。我这里只写了两个,实际这里面可以写多个,要看到时候咱们的编写需求,里面位置也可以调换,当然这个注解也可以放在类上面。
运行结果:
AInterceptor.....
BInterceptor.....
不过DemoConfig.java里的全局拦截器就只能一个一个add方法分开来加了。没有多个形参的add方法。执行顺序从上到下。
@Clear注解:
拦截器从上到下依次分为Global、Inject、Class、Method四个层次,Clear用于清楚自身所处层次以上层的拦截器(不包括与自身同级的拦截器)@Clear可以带拦截器参数,写法和@Before一致。
@Clear
public void index(){
String msg = getPara("msg", "defaultMesg");
String[] v= getParaValues("test");
setAttr("msg" , "hello,jfinal 3.0----->"+msg);
renderJsp("index.jsp");
}
调用这个方法时,上层的拦截器全部清除。上层拦截器的没有打印结果,说明没有走到拦截器内。
@Clear(ClassInterceptor.class)
public void index(){
String msg = getPara("msg", "defaultMesg");
String[] v= getParaValues("test");
setAttr("msg" , "hello,jfinal 3.0----->"+msg);
renderJsp("index.jsp");
}
在@Clear注解后面加了参数时,代表指定某拦截器失效。
打印结果:
GlobalInterceptor...
当然可以写多个参数。
@Clear({ClassInterceptor.class,GlobalInterceptor.class})
public void index(){
String msg = getPara("msg", "defaultMesg");
String[] v= getParaValues("test");
setAttr("msg" , "hello,jfinal 3.0----->"+msg);
renderJsp("index.jsp");
}
然后还有就是@Clear不会清除与自己同级和下级的拦截器。
@Before(MethodInterceptor.class)
@Clear({MethodInterceptor.class,ClassInterceptor.class,GlobalInterceptor.class})
public void index(){
String msg = getPara("msg", "defaultMesg");
String[] v= getParaValues("test");
setAttr("msg" , "hello,jfinal 3.0----->"+msg);
renderJsp("index.jsp");
}
我这样写运行结果method和class级别的拦截器并不会失效。
ClassInterceptor.....
methodInterceptor.....