1. 서문
이전 프로젝트에서는 Spring AOP의 특정 구현 및 이론에 거의주의를 기울이지 않았습니다. AOP가 무엇인지, 사용 방법을 간단히 이해했습니다. 잘 쓰여진 블로그 게시물을 보았으므로 배우기 위해 왔습니다.
AOP
AOP (Aspect-Oriented Programming), 즉 Aspect-Oriented Programming은 OOP (Object Oriented Programming)의 보충 및 개선이라고 할 수 있습니다. OOP는 캡슐화, 상속 및 다형성과 같은 개념을 소개하여 공개 행동 모음을 시뮬레이션하는 데 사용되는 객체 계층 구조를 설정합니다. 그러나 OOP를 사용하면 개발자가 수직 관계를 정의 할 수 있지만 로깅 함수와 같은 수평 관계를 정의하는 데 적합하지 않습니다. 로그 코드는 종종 모든 객체 수준에서 수평으로 흩어져 있으며 해당 객체의 핵심 함수와 관련이 없습니다. 모든 곳에서 흩어져있는 이런 종류의 관련된 코드를 크로스 절단이라고합니다. OOP 설계에서는 많은 양의 코드 복제를 유발하며 각 모듈의 재사용에는 도움이되지 않습니다.
반대로 AOP 기술은 "Crosscutting"이라는 기술을 사용하여 캡슐화 된 객체의 내부를 해부하고 여러 클래스에 영향을 미치는 일반적인 동작을 재사용 가능한 모듈에 영향을 미치는 일반적인 동작을 캡슐화하고 Facet 인 "측면"이라고 명명합니다. 소위 "섹션"은 비즈니스와 관련이 없지만 비즈니스 모듈에 의해 공동으로 호출되는 논리 또는 책임에 의해 단순히 캡슐화되며, 이는 시스템의 중복 코드를 줄이고 모듈 간의 커플 링을 줄이며 향후 운영 가능성과 유지 관리에 도움이됩니다.
"크로스 컷팅"기술을 사용하여 AOP는 소프트웨어 시스템을 핵심 관심사와 교차 절단 문제의 두 부분으로 나눕니다. 비즈니스 처리의 주요 프로세스는 핵심 초점이며, 이와 관련하여 거의 관련이없는 부분은 단면 초점입니다. 교차 절단 문제의 특징 중 하나는 여러 핵심 문제에서 종종 발생하며 기본적으로 권한 인증, 로그 및 사물과 같은 다양한 장소에서 유사하다는 것입니다. AOP의 역할은 시스템에서 다양한 문제를 분리하고 핵심 문제를 교차 절단 문제와 분리하는 것입니다.
AOP 핵심 개념
1. 크로스 컷주의 지점
인터셉트하는 방법과 가로 채기 후에 그것을 다루는 방법은 무엇입니까? 이러한 문제를 교차 절단 문제라고합니다
2. 섹션 (측면)
클래스는 객체의 특징의 추상화이며, 섹션은 교차 문제의 추상화입니다.
3. JoinPoint
스프링은 메소드 유형 연결 지점 만 지원하므로 차단 된 지점은 스프링의 연결 지점은 가로 채워진 메소드를 나타냅니다. 실제로 연결 지점은 필드 또는 생성자 일 수도 있습니다.
4. 포인트 컷
연결 지점을 가로 채기의 정의
5. 알림 (조언)
소위 알림은 연결 지점을 가로 채운 후 실행될 코드를 말합니다. 알림은 사전 설정, 사후 설정, 예외, 최종 및 주변 알림의 5 가지 범주로 나뉩니다.
6. 대상 객체
프록시의 대상 객체
7. 직조
슬릿을 대상 객체에 적용하고 프록시 객체 생성을 일으키는 과정
8. 소개
코드를 수정하지 않고 소개는 런타임 기간 동안 클래스에 일부 방법이나 필드를 동적으로 추가 할 수 있습니다.
AOP에 대한 봄의 지원
Spring의 AOP 에이전트는 Spring의 IOC 컨테이너의 생성 및 관리를 담당하며 그 종속성은 IOC 컨테이너에 의해 관리됩니다. 따라서 AOP 프록시는 컨테이너의 다른 Bean 인스턴스를 직접 타겟팅 할 수 있으며,이 관계는 IOC 컨테이너의 의존성 주입에 의해 제공 될 수 있습니다. 봄에 프록시를 만드는 규칙은 다음과 같습니다.
1. 기본적으로 Java Dynamic Proxy는 AOP 프록시를 만드는 데 사용되므로 모든 인터페이스 인스턴스에 대한 프록시를 만들 수 있습니다.
2. 프록시가 필요한 클래스가 프록시 인터페이스가 아닌 경우 Spring은 CGLIB 프록시를 사용하여 전환하고 CGLIB를 사용하도록 할 수도 있습니다.
AOP 프로그래밍은 실제로 매우 간단한 것입니다. AOP. 프로그래밍을 살펴보면 프로그래머는 세 부분에만 참여하면됩니다.
1. 일반 비즈니스 구성 요소를 정의하십시오
2. 진입 점을 정의하면 하나의 진입 점이 여러 비즈니스 구성 요소를 교차 절단 할 수 있습니다.
3. 향상된 처리를 정의합니다. 향상된 처리는 AOP 프레임 워크의 일반 비즈니스 구성 요소로 직조되는 처리 작업입니다.
따라서 AOP 프로그래밍의 핵심은 진입 점을 정의하고 향상 처리를 정의하는 것입니다. 적절한 진입 점 및 향상 처리가 정의되면 AOP 프레임 워크는 AOP 프록시, 즉 프록시 오브젝트 = 향상 처리 + 프록시 오브젝트의 방법을 자동으로 생성합니다.
다음은 aop.xml이라는 Spring AOP .XML 파일 템플릿이며 후속 내용은 aop.xml에서 확장됩니다.
<? xml 버전 = "1.0"alcoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : xsi = "http://ww.w.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.springframwork.org/schema/schema/schemas http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> </beans>
스프링을 기반으로 한 AOP의 간단한 구현
설명하기 전에 설명하겠습니다. 코드를 성공적으로 실행하려면 Spring이 제공 한 JAR 패키지를 개발자에게 사용하는 것만으로는 충분하지 않습니다. 온라인으로 두 개의 JAR 패키지를 다운로드하십시오.
1. aopalliance.jar
2. SAGONTJWEAVER.jar
Spring AOP의 XML 구현 방법을 설명하고 먼저 인터페이스를 정의하겠습니다.
공개 인터페이스 helloworld {void printhelloworld (); void doprint ();} 두 개의 인터페이스 구현 클래스 정의 :
공개 클래스 helloworldimpl1은 helloworld {public void printhelloworld () {system.out.println을 구현합니다 ( "helloworldimpl1.printhelloworld ()"); } public void doprint () {system.out.println ( "helloworldimpl1.doprint ()"); 반품 ; }} 공개 클래스 helloworldimpl2 Helloworld {public void printhelloworld () {system.out.println ( "helloworldimpl2.printhelloworld ()를 입력합니다."); } public void doprint () {system.out.println ( "helloworldimpl2.doprint ()를 입력합니다."); 반품 ; }} 크로스 컷팅 초점은 여기에 인쇄 시간이 있습니다.
public class timehandler {public void printtime () {system.out.println ( "currentTime =" + system.currentTimeMillis ()); }} 이 세 클래스를 사용하면 간단한 스프링 AOP를 구현할 수 있습니다. aop.xml의 구성을 살펴보십시오.
<? xml 버전 = "1.0"alcoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : xsi = "http://ww.w.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.springframwork.org/schema/schema/schemas http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id ="helloworldimpl1 "/> <bean id ="helloworldimpl2 "/> <bean id ="timehandler "/> <aop : config> <aop : time" "time" "" "" "" "" "" "" "" "" "" "" ""time ""time ""time ""time ""time ""time ""time ""time ""helloorldimpl2 "/> id = "addAllMethod"expression = "execution (* com.xrq.aop.helloworld.* (..))") " /> <aop : 이전 메소드 ="printtime "pointcut-ref ="addallmethod " /> <aop : after method ="printtime "pointcut-ref ="addallMethod " /> < /aop : aspect> < /a < /a < /ap> < /aop> < /aop.
그것을 호출 할 주요 기능을 작성하십시오.
public static void main (string [] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext ( "aop.xml"); helloworld hw1 = (helloworld) ctx.getbean ( "helloworldimpl1"); helloworld hw2 = (helloworld) ctx.getbean ( "helloworldimpl2"); hw1.printhelloworld (); System.out.println (); hw1.doprint (); System.out.println (); System.out.println (); hw2.printhelloworld (); System.out.println (); hw2.doprint ();} 실행 결과는 다음과 같습니다.
CurrentTime = 1446129611993ENTER HelloWorlDimpl1.prinThellowORLD () currentTime = 1446129611993CurrentTime = 144612961194Enter HelloWorlDimpl1.doprint () currenttime = 144612961194CurrentTER helloworldimpl2.printhelloworld () currenttime = 144612961194currentTime = 1446129611994ENTER HelloWorlDimpl2.Doprint () currenttime = 1446129611994
Helloworld 인터페이스의 두 구현 클래스의 모든 방법이 프록시에 추가되었으며 프록시 컨텐츠는 인쇄 시간입니다.
스프링 기반 AOP 사용에 대한 추가 세부 사항
1. 교차 절단 문제를 추가하고 로그를 인쇄하십시오. Java 클래스는 다음과 같습니다.
public class loghandler {public void logbefore () {system.out.println ( "log 이전 메소드"); } public void logafter () {system.out.println ( "Method After Method"); }}<? xml 버전 = "1.0"alcoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : xsi = "http://ww.w.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.springframwork.org/schema/schema/schemas http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id ="helloworldimpl1 "/> <bean id ="helloworldimpl2 "/> <bean id ="timehandler "/> <bean id ="logandhandler "/> <aop : config> <a : at id =" "". order = "1"> <aop : pointcut id = "addtime"expression = "execution (* com.xrq.aop.helloWorld.* (..))") " /> <aop : prection 메소드 ="printtime "pointcut-Ref ="addtime " /<aop : after :"platttime "pointcut-ref ="addtime " /<aop : <aop : <aop : <aop. ref = "loghandler"order = "2"> <aop : pointcut id = "printlog"expression = "execution (* com.xrq.aop.hellow.HellowOrld.* (..))") ")") ")" /> <aop : "method ="logbefore "pointCut-Ref ="printlog " /> <aop : method ="logafter ""printlog ": <printlog" </aop : config> </beans>
테스트 클래스는 변경되지 않은 상태로 유지되며 인쇄 결과는 다음과 같습니다.
currenttime = 1446130273734 Methodenter helloorldimpl1.printhelloworld () log 이전의 methodcurrenttime = 1446130273735currenttime = 14461302737366log 이전에 helloworldimpl1.doprintttime = 1446130273334currenttite = 144613027334 1446130273736 Methodenter HelloWorldimpl2.printhelloworld () 로그 이전의 메소드 CurrentTime = 144613027366CurrentTime = 1446130273737737 Log 이전의 HelloWorldimpl2.doprint () 후 로그 이전의 방법 = 1446130273731302737313027373737
TimeHandler 전에 로그 핸들러를 사용하는 두 가지 방법이 있습니다.
(1) 측면에 주문 속성이 있으며, 주문 속성의 수는 포커스 포인트를 크로스 절개하는 순서입니다.
(2) TimeHandler 전에 로그 핸들러를 정의하십시오. 스프링은 기본적으로 정의 순서를 직조 순서로 사용합니다.
2. 나는 단지 몇 가지 방법을 인터페이스에 짜고 싶다.
포인트 컷 표현식 만 수정하십시오.
<? xml 버전 = "1.0"alcoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : xsi = "http://ww.w.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.springframwork.org/schema/schema/schemas http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.spramework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id ="helloworldimpl1 "/> <bean id ="helloworldimpl2 "/> <bean id ="timehandler "/> <bean id ="logandhandler "/> <aop : config> <a : at id =" "". order = "1"> <aop : pointcut id = "addtime"expression = "execution (* com.xrq.aop.helloworld.print* (..))" /> <aop : prever method = "printtime"pointcut-Ref = "addtime" /> <aop : "printtime"pointcut-Ref = "addtime" /<aop : <aop : <aop : " ref = "loghandler"order = "2"> <aop : pointcut id = "printlog"expression = "execution (* com.xrq.aop.hellohorld.do* (..))" /> <aop : "logbefore"pointcut-Ref = "printlog" /> <aop : after = "logafter": <printlog " /aop. </aop : config> </beans>
그것은 TimeHandler가 HelloWorld 인터페이스 인쇄의 시작 부분에서 시작하는 방법 만 직조한다는 것을 의미하며, Loghandler
3. CGLIB가 프록시를 생성하도록 강제
앞에서 언급했듯이 Spring은 동적 프록시 또는 CGLIB를 사용하여 프록시를 생성합니다. 더 높은 버전의 스프링은 동적 프록시 또는 CGLIB를 사용하여 프록시 컨텐츠를 생성할지 자동으로 선택합니다. 물론 CGLIB가 프록시를 생성하도록 강요 할 수도 있습니다. 이 속성 값이 true로 설정되면 클래스 기반 프록시가 작동합니다. 프록시-표적 클래스가 False로 설정 되거나이 속성이 생략되면 인터페이스 기반 프록시가 작동합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.