版权声明:From Lay https://blog.csdn.net/Sadlay/article/details/83478481
AOP的引入
引入就是在一个接口的基础上引入新的接口增强功能。
在上一篇博客中测试AOO的时候,我们打印了用户信息,如果用户信息为空,则抛出异常。
事实上,我们还可以检测用户信息是否为空,如果为空则不再打印,这样就没有异常产生了。
但现有的UserService接口并没有提供这样的功能,这里假定UserService这个服务并不是自己所提供,而是别人提供的,我们不能修改它,这时Spring还允许增强这个接口的功能,我们可以为这个接口引入新的接口。例如,要引入一个用户检测的接口UserValidator,定义如下
UserValidator接口
package com.lay.springboot_aop.aspect.validator;
import com.lay.springboot_aop.aspect.pojo.User;
public interface UserValidator {
public boolean validate(User user);
}
UserValidatorImpl实现类
package com.lay.springboot_aop.aspect.validator.impl;
import com.lay.springboot_aop.aspect.pojo.User;
import com.lay.springboot_aop.aspect.validator.UserValidator;
public class UserValidatorImpl implements UserValidator {
@Override
public boolean validate(User user) {
System.out.println("引入新的接口" + UserValidator.class.getSimpleName());
return user != null;
}
}
这样,我们通过Spring AOP引入的定义就能够增强UserService接口的功能,然后我们在切面类中加入如下代码
MyAspect切面
package com.lay.springboot_aop.aspect;
@Aspect
public class MyAspect {
@DeclareParents(value = "com.lay.springboot_aop.aspect.service.impl.UserServiceImpl*", defaultImpl = UserValidatorImpl.class)
public UserValidator userValidator;
@Pointcut("execution(* com.lay.springboot_aop.aspect.service.impl.UserServiceImpl.printUser(..))")
public void pointCut() {
}
@Before("pointCut()&&args(user)")
public void before(JoinPoint point ,User user) {
Object[] args=point.getArgs();
User a= (User)args[0];
System.out.println("print in before"+user.getUserName());
System.out.println("\nprint in before args = "+a.getUserName());
System.out.println("before-----------");
}
@Around("pointCut()")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("around before-------------");
jp.proceed();
System.out.println("around after-------------");
}
@After("pointCut()")
public void after() {
System.out.println("after------------");
}
@AfterReturning("pointCut()")
public void afterReturning() {
System.out.println("afterReturning------------");
}
@AfterThrowing("pointCut()")
public void afterThrowning() {
System.out.println("afterThrowning------------");
}
}
这里我们看到了一个新的注解@DeclareParents,它的作用是引入新的类来增强服务,但它有两个必须配置的属性value和defalutImpl。
- value:指向你要增强功能的目标对象,这里要增强UserServiceImpl对象
- defaultImpl:引入增强功能的类,这里配置为UserValidatorImpl,用来提供校验用户是否为空的功能。
测试
UserController
package com.lay.springboot_aop.aspect.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lay.springboot_aop.aspect.pojo.User;
import com.lay.springboot_aop.aspect.service.UserService;
import com.lay.springboot_aop.aspect.validator.UserValidator;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService=null;
@RequestMapping("/vap")
@ResponseBody
public User validateAndPrintUser(Integer id,String userName,String message) {
User user=new User();
user.setId(id);
user.setUserName(userName);
user.setMessage(message);
UserValidator userValidator=(UserValidator)userService;
if(userValidator.validate(user)) {
userService.printUser(user);
}
return user;
}
}
然后启动工程,在浏览器输入http://localhost:8080/user/vap?id=1&userName=username&message=somemessage