目前我们正在将Struts 1.1项目迁移到Spring 4.x.
我们已经成功地将Action类转换为Controller并将formbean转换为Model,甚至我们也能够将struts验证转换为Spring验证.
但是当我们尝试为所有控制器添加AOP时,我们遇到了一个问题.
目的是添加一个日志来测量所有控制器方法所需的时间.
下面是代码片段,
@Component
@Controller
public class LoginController {
@Autowired
private LoginValidator loginValidator;
@InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(loginValidator);
}
@RequestMapping(value = "/login",method = RequestMethod.POST)
public String loginUser(@Valid @modelattribute Login form,BindingResult bindingResult) {
System.out.println("Entering loginController.loginUser method");
}
}
我们使用下面的切点来应用aop,
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class Logging {
@Pointcut("execution(* com.controller.*.*(..))")
public void businessLogicMethods() {}
@Around("businessLogicMethods()")
public Object logAround(ProceedingJoinPoint jp) {
System.out.println("around() is running!");
System.out.println(jp.getSignature().getName());
System.out.println(jp.getArgs());
Object obj = null;
try {
obj = jp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("******");
return obj;
}
}
验证或AOP一次正在运行.如果未应用AOP,则触发验证.如果应用aop,则仅触发AOP.
任何人都可以帮忙吗?
谢谢…
最佳答案
我得到了这个工作.你必须做2次更改.
改变号码:1
>出于某种原因,您的Aspect定义是错误的.(不知道为什么).但是以下方面将起作用.
@Component
@Aspect
public class Logging {
static final Logger LOG = LoggerFactory.getLogger(Logging.class);
@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() {}
@Pointcut("execution(* *(..))")
public void methodPointcut() {}
@Pointcut("within(@org.springframework.web.bind.annotation.RequestMapping *)")
public void requestMapping() {}
@Before("controller() && methodPointcut() && requestMapping()")
public void aroundControllerMethod(JoinPoint joinPoint) throws Throwable {
LOG.info("Invoked: " + niceName(joinPoint));
}
@AfterReturning("controller() && methodPointcut() && requestMapping()")
public void afterControllerMethod(JoinPoint joinPoint) {
LOG.info("Finished: " + niceName(joinPoint));
}
private String niceName(JoinPoint joinPoint) {
return joinPoint.getTarget().getClass()
+ "#" + joinPoint.getSignature().getName()
+ "\n\targs:" + Arrays.toString(joinPoint.getArgs());
}
}
改变号码:2
initBinder应该声明为public.目前,您已将此方法定义为私有.我再次不确定为什么没有这些方面,这项工作是正确的.
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(loginValidator);
}
这两个变化将起作用.