1. 程式人生 > >Spring AOP(五)引入

Spring 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