Я помню, когда я начал интервью в начале этого года, наиболее часто задаваемый вопрос был: знаете ли вы два ядра Spring? Итак, что вы подразумеваете под АОП и что такое IOC? Я уверен, что вас, вероятно, тоже спрашивали много раз.
1. Что такое АОП?
Так называемый АОП — это аспектно-ориентированное программирование, позволяющеепоперечный разрезРасширяйте с помощью новых функций. Здесь есть более заметное слово, на которое нужно обратить внимание, сквозное, которое расширяет программу, основанную на сквозном.
2. Термины, связанные с АОП
В АОП Spring много терминов, и их легко спутать.Сначала вы должны понять эти понятия:
Точка присоединения: в определенный момент выполнения программы, например, перед инициализацией класса, после инициализации класса, перед вызовом метода и после вызова метода;
Точка отсечки(Pointcut): Так называемый pointcut — это метод в классе, который вы разрезаете.Например, если в классе, который вы разрезаете, есть два метода, то эти два метода являются точками соединения, и позиционирование этих двух методов называется pointcut ;
Повышенная (Advice): Улучшение — это программа, вплетенная в точку подключения, а также в ней есть информация о точке подключения;
Целевой объект (Цель): Целевой класс расширенной логики — это место, где имплантирована моя расширенная логика;
ВведениеIntroduction): специальное расширение, добавляющее некоторые свойства и методы к классу;
ткать (Weaving): Weaving — это процесс добавления расширенной логики к целевому объекту;
играет роль(Proxy): после того, как класс вплетен в АОП и улучшен, будет сгенерирован результирующий класс, который является прокси-классом, сочетающим в себе исходный класс и расширенную логику;
раздел(Aspect): Аспект состоит из точек касания и расширений, которые состоят из сквозных логических определений и определений точек соединения;
3. Практика функций АОП
В основном мы изучаем некоторые функции в SpringBoot, поэтому здесь мы используем проект SpringBoot, и версия также является последней версией 2.0.5.
Не будем говорить о создании проекта SpringBoot, непосредственно представим зависимости Maven:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- 引入AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
</executions>
</plugin>
</plugins>
</build>
Сначала создадим класс контроллера:
@RestController
public class LoginController {
@GetMapping(value = "/username")
public String getLoginUserName(String userName, Integer age) {
return userName + " --- " + age;
}
}
Создайте фрагмент:
@Aspect
@Component
public class LogAspect {
/**
* 功能描述: 拦截对这个包下所有方法的访问
*
* @param:[]
* @return:void
**/
@Pointcut("execution(* com.example.springbootaop.controller.*.*(..))")
public void loginLog() {
}
// 前置通知
@Before("loginLog()")
public void loginBefore(JoinPoint joinPoint) {
// 我们从请求的上下文中获取request,记录请求的内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
System.out.println("请求路径 : " + request.getRequestURL());
System.out.println("请求方式 : " + request.getMethod());
System.out.println("方法名 : " + joinPoint.getSignature().getName());
System.out.println("类路径 : " + joinPoint.getSignature().getDeclaringTypeName());
System.out.println("参数 : " + Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "object", pointcut = "loginLog()")
public void doAfterReturning(Object object) {
System.out.println("方法的返回值 : " + object);
}
// 方法发生异常时执行该方法
@AfterThrowing(throwing = "e",pointcut = "loginLog()")
public void throwsExecute(JoinPoint joinPoint, Exception e) {
System.err.println("方法执行异常 : " + e.getMessage());
}
// 后置通知
@After("loginLog()")
public void afterInform() {
System.out.println("后置通知结束");
}
// 环绕通知
@Around("loginLog()")
public Object surroundInform(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("环绕通知开始...");
try {
Object o = proceedingJoinPoint.proceed();
System.out.println("方法环绕proceed,结果是 :" + o);
return o;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
}
Обзор аннотации:
@Apsect: идентифицирует текущий класс как аспект;
@Pointcut: определить pointcut, вот условное выражение;
@Before: Способ расширения переднего расширения выполнен перед выполнением;
@AfterReturning: Усиление сзади выполняется при выходе из метода;
@AfterThrowing: метод выполняется при возникновении исключения;
@After: Финальное улучшение, которое будет выполнено в любой ситуации;
@Afround: улучшение объемного звучания;
контрольная работа:
Тест исключения:
4. Определите пользовательские аннотации
Сценарии применения: Когда я последний проект раньше, есть такой комментарий, это необходимость входа в систему при доступе к другим интерфейсам, поэтому на этот раз мы определяем комментарий, пусть он идет, чтобы проверить, вошел ли пользователь в систему, поэтому на основе этой сцены, мы определяем заметки журнала проверки.
Создайте аннотацию:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {
String desc() default "验证是否登录";
}
Создайте АОП-аспект:
@Aspect
@Component
public class LoginAspect {
@Pointcut(value = "@annotation(com.example.springbootaop.annotation.Auth)")
public void access() {
}
@Before("access()")
public void before() {
System.out.println("开始验证用户是否登录...");
}
@Around("@annotation(auth)")
public Object around(ProceedingJoinPoint pj, Auth auth) {
// 获取注解中的值
System.out.println("注解中的值 : " + auth.desc());
try {
// 检验是否登录 true 已经登录 false 未登录
Boolean flag = false;
if (flag == true) {
return "登录成功";
} else {
return "未登录";
}
} catch (Throwable throwable) {
return null;
}
}
}
Тест не авторизован:
Тестовый вход:
Таким образом, мы можем просто реализовать аннотацию проверки входа.
С сегодняшней акцией вы уже использовали пользовательские аннотации и АОП? Я помещаю адрес на источник ниже, заинтересованные друзья могут видеть.
Адрес GitHub: https://GitHub.com/два храма/интеграция весенней загрузки.git
Оригинальность — это непросто, если вам хорошо, ставьте 👍 и распространяйте!
Для получения дополнительной информации, пожалуйста, следуйте"Рост программиста"