1. Что такое АОП?
Если говорить об АОП, то что такое АОП? АОП — это аспектно-ориентированное программирование.类,实例
, естественно думать, что самой базовой единицей АОП может быть так называемая切面
, вы можете спросить, что切面
Что это такое, я хочу сказать, неважно, если вы этого не понимаете сейчас, я расскажу об этом позже. Давайте сначала посмотримSpring
Определение АОП в:
Аспектно-ориентированный — Spring обеспечивает богатую поддержку аспектно-ориентированного программирования, обеспечивая целостную разработку, отделяя бизнес-логику приложения от сервисов системного уровня, таких как аудит и управление транзакциями. Объекты приложения делают только то, что должны делать — завершают бизнес-логику — и ничего больше. Они не несут ответственности (и даже не осведомлены) о других проблемах системного уровня, таких как ведение журнала или поддержка транзакций.
Как было сказано выше, АОП может разделять бизнес-логику системы и системные сервисы (логи, безопасность и т.д.), думаю, разобраться в этой функции несложно (принцип использования代理模式
), но смысл в том, зачем разделять их? Или каковы преимущества этого?
При ежедневной разработке программного обеспечения, взяв в качестве примера журналы, разработка системного программного обеспечения должна быть записана, иначе, если в системе будет какая-либо ошибка, вы не будете знать, в чем проблема. Например, когда вы разрабатываете функцию входа в систему, вам может потребоваться выполнить проверку разрешений до и после входа пользователя и проверить информацию (用户名
,密码
,请求登陆时间,ip地址
и т. д.) записываются в лог-файл.После входа пользователя в систему, когда он обращается к какой-либо другой функции, ее также необходимо проверить на валидность. Вдумайтесь, когда система очень большая, кодов для проверки авторизации в системе очень много, и она сильно разбросана, интересно, можно ли разделить эти функции, не связанные с бизнес-логикой, такие как проверка авторизации и логирование, отдельно. , и, где это необходимо, во время выполнения системы (连接点
) выполнять операцию динамической вставки и игнорировать ее, когда она не нужна, так что АОП — это идея, которая может решить эту ситуацию!
На следующем рисунке этот процесс наглядно показан:
Во-вторых, основные концепции АОП.
Я должен сказать, что концепций АОП действительно много и они трудны для понимания, но не волнуйтесь, вы умны и готовы победить их.
- Совет
Существует 5 типов уведомлений:
-
Before
вызывается перед вызовом метода -
After
Вызывать уведомления после завершения метода, независимо от того, был ли метод успешно выполнен или нет. -
After-returning
Вызывать уведомление после успешного выполнения метода -
After-throwing
Совет по вызову после того, как метод выдает исключение -
Around
Уведомление и включение уведомленного метода, выполнение пользовательского поведения до и после вызова уведомленного методаМы можем спросить, является ли код в соответствующей системе уведомлений методом, объектом, классом, интерфейсом или чем-то еще? Я хотел бы сказать одно, но это не так. Вы можете понять, что уведомление соответствует предупреждению в нашей повседневной жизни, например: «Такой-то, вы приходите в школу 1 сентября 2019 года, чтобы отчитаться перед school», уведомление в большей степени отражает a. Оно сообщает нам (сообщает системе, что), когда выполнять, указывает время, в определенный момент системной операции (например, создание исключения! Перед выполнением метода!),
并非对应代码中的方法!并非对应代码中的方法!并非对应代码中的方法!
-
Точечная резка
Ха-ха, вам может быть легче понять, pointcut действительно является методом в соответствующей системе в Spring AOP. Но этот метод является методом, определенным в аспекте, и обычно используется с советом для формирования аспекта.
-
Точка присоединения
Например: вызов метода, выполнение метода, установка/получение поля, выполнение обработки исключений, инициализация класса или даже точка в цикле for.
Теоретически любая точка во время выполнения программы может быть использована в качестве точки переплетения, и все эти точки выполнения являются точками соединения.
Но Spring AOP в настоящее время поддерживает только выполнение метода (выполнение метода) Это можно понять и таким образом, точка присоединения — это место, где вы собираетесь выполнять в системе pointcut и pointcut совета (обычно это метод, поле)
-
Аспект
Аспект представляет собой набор точек и советов, как правило, в виде одного класса. Вместе советы и точки определяют, что представляет собой аспект, когда, когда и где он выполняет функциональность.
-
Введение
Ссылки позволяют нам добавлять новые методы или свойства в существующий класс.
-
Ткачество
Соберите аспект, чтобы создать уведомленный объект. Это можно сделать во время компиляции (например, с помощью компилятора AspectJ) или во время выполнения. Spring, как и другие чистые среды Java AOP, выполняет переплетение во время выполнения.
3. Поддержка АОП в Spring
Прежде всего, реализация идеи АОП вообще основана на режиме прокси.В JAVA обычно используется режим динамического прокси JDK, но мы все знаем, что режим динамического прокси JDK может только проксировать интерфейс, и если вы хотите проксировать класс, не получится. Поэтому Spring AOP будет переключаться таким образом, потому что Spring AOP одновременно поддерживает динамический прокси CGLIB, ASPECTJ и JDK.Когда ваш реальный объект имеет интерфейс реализации, Spring AOP по умолчанию будет использовать динамический прокси JDK, в противном случае он будет использовать cglib прокси.
- Если класс реализации целевого объекта реализует интерфейс, Spring AOP будет использовать динамический прокси-сервер JDK для создания класса прокси-сервера AOP;
- Если класс реализации целевого объекта не реализует интерфейс, Spring AOP будет использовать CGLIB для генерации прокси-класса AOP, но этот процесс выбора полностью прозрачен для разработчика, и разработчику не нужно заботиться об этом.
В-четвертых, после стольких слов, давайте утолим вашу жажду печеньем! Перейти непосредственно к коду!
Может ли печенье утолить жажду?
- Определяем предметные интерфейсы, методы которых могут стать нашими
连接点
package wokao666.club.aop.spring01;
public interface Subject {
//登陆
public void login();
//下载
public void download();
}
- Определите класс реализации, который является реальным принципалом в режиме прокси (если вы участвуете в закупках, это похоже на вашу роль в закупках)
package wokao666.club.aop.spring02;
import wokao666.club.aop.spring01.Subject;
public class SubjectImpl implements Subject {
public void login() {
System.err.println("借书中...");
}
public void download() {
System.err.println("下载中...");
}
}
- Определите аспект (в аспекте есть точки и советы)
package wokao666.club.aop.spring01;
import org.aspectj.lang.JoinPoint;
public class PermissionVerification {
/**
* 权限校验
* @param args 登陆参数
*/
public void canLogin() {
//做一些登陆校验
System.err.println("我正在校验啦!!!!");
}
/**
* 校验之后做一些处理(无论是否成功都做处理)
* @param args 权限校验参数
*/
public void saveMessage() {
//做一些后置处理
System.err.println("我正在处理啦!!!!");
}
}
- взгляните на наш
SpringAOP.xml
документ
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="SubjectImpl1" class="wokao666.club.aop.spring02.SubjectImpl" />
<bean id="SubjectImpl2" class="wokao666.club.aop.spring02.SubjectImpl" />
<bean id="PermissionVerification" class="wokao666.club.aop.spring01.PermissionVerification" />
<aop:config>
<!-- 这是定义一个切面,切面是切点和通知的集合-->
<aop:aspect id="do" ref="PermissionVerification">
<!-- 定义切点 ,后面是expression语言,表示包括该接口中定义的所有方法都会被执行-->
<aop:pointcut id="point" expression="execution(* wokao666.club.aop.spring01.Subject.*(..))" />
<!-- 定义通知 -->
<aop:before method="canLogin" pointcut-ref="point" />
<aop:after method="saveMessage" pointcut-ref="point" />
</aop:aspect>
</aop:config>
</beans>
- Поскольку я строю на MAVEN, взгляните на наш
pom.xml
документ
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>wokao666.club</groupId>
<artifactId>aop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>aop</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.0.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
</dependencies>
</project>
- Последний взгляд на наши тестовые классы и результаты
package wokao666.club.aop.spring01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("SpringAOP.xml");
Subject subject1 = (Subject)ctx.getBean("SubjectImpl1");
Subject subject2 = (Subject)ctx.getBean("SubjectImpl2");
subject1.login();
subject1.download();
System.err.println("==================");
subject1.login();
subject1.download();
}
}
三月 13, 2018 4:59:44 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Tue Mar 13 16:59:44 CST 2018]; root of context hierarchy
三月 13, 2018 4:59:45 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [SpringAOP.xml]
我正在校验啦!!!!
借书中...
我正在处理啦!!!!
我正在校验啦!!!!
下载中...
我正在处理啦!!!!
==================
我正在校验啦!!!!
借书中...
我正在处理啦!!!!
我正在校验啦!!!!
下载中...
我正在处理啦!!!!
Я думаю, вышеприведенная реализация - это всего лишь скин! Если хотите узнать больше, можете посмотреть анализ исходного кода динамического прокси JDK (он очень умный, да еще и использует кеш второго уровня. Я изначально хотел его написать, оставлю на следующий статьи!), анализ исходного кода Spring AOP и т. д. Конечно, описанный выше метод реализации основан на старомодном xml файле, нам не рекомендуется этого делать, почему? Я думаю, когда ваша система станет больше, будет многоbean
,xml
файл, который нелегко поддерживать и управлять, я полагаю, что подход к АОП-программированию, основанный на аннотациях, был бы лучше!
Ну, я хотел закончить, но перед закрытием eclipse обнаружил небольшую проблему, поскольку pointcut - это метод, который необходимо выполнить, то как мы получим данные точки подключения (или параметр проверки?), это рекомендуется здесь Сообщение в блоге, я не буду его писать! Ребята, давайте работать вместе!