Spring 학습 총 결―Spring 실현 AOP 의 다양한 방식
1.XML 기반 Spring AOP
2.주석 설정 AOP 사용
3.AspectJ 절 점 함수
4.AspectJ 알림 주해
5.제로 설정 은 Spring IoC 와 AOP 를 실현 합 니 다.
AOP(Aspect Oriented Programming)는 절단면 을 대상 으로 프로 그래 밍 하고 사전 컴 파일 방식 과 런 타임 동적 대 리 를 통 해 프로그램 기능 을 수행 하 는 가로 다 중 모듈 을 통일 적 으로 제어 하 는 기술 이다.AOP 는 OOP 의 보충 으로 spring 프레임 워 크 의 중요 한 내용 이다.AOP 를 이용 하여 업무 논리의 각 부분 을 격 리 하여 업무 논리의 각 부분 간 의 결합 도 를 낮 추고 프로그램의 중용 성 을 높이 는 동시에 개발 의 효율 을 높 일 수 있다.AOP 는 정적 인 짜 임 과 동적 인 짜 임 으로 나 눌 수 있 습 니 다.정적 인 짜 임 은 컴 파일 하기 전에 내용 을 짜 서 목표 모듈 에 기록 해 야 합 니 다.이렇게 하면 비용 이 매우 높 습 니 다.동적 삽입 은 목표 모듈 을 바 꿀 필요 가 없습니다.Spring 프레임 워 크 는 AOP 를 구현 하 였 으 며,주석 설정 을 사용 하여 AOP 를 완성 하 는 것 이 XML 설정 을 사용 하 는 것 보다 더욱 편리 하고 직관 적 입 니 다.
1.XML 기반 Spring AOP
주 해 를 말 하여 AOP 기능 을 실현 하기 전에 앞에서 배 운 xml 로 Spring AOP 기능 을 설정 하 는 것 은 비교 하여 더욱 잘 이해 하도록 하기 위 한 것 이다.
1.1 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>com.zhangguo</groupId>
<artifactId>Spring052</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spring052</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>
1.2.대리 할 Math 클래스 를 만 듭 니 다.코드 는 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop01;
/**
*
*/
public class Math{
//
public int add(int n1,int n2){
int result=n1+n2;
System.out.println(n1+"+"+n2+"="+result);
return result;
}
//
public int sub(int n1,int n2){
int result=n1-n2;
System.out.println(n1+"-"+n2+"="+result);
return result;
}
//
public int mut(int n1,int n2){
int result=n1*n2;
System.out.println(n1+"X"+n2+"="+result);
return result;
}
//
public int div(int n1,int n2){
int result=n1/n2;
System.out.println(n1+"/"+n2+"="+result);
return result;
}
}
1.3 AOP 에서 사용 할 알림 클래스 를 편집 합 니 다 Advices.Java 코드 는 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop01;
import org.aspectj.lang.JoinPoint;
/**
* ,
*
*/
public class Advices {
public void before(JoinPoint jp){
System.out.println("---------- ----------");
System.out.println(jp.getSignature().getName());
}
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
}
1.4.용기 초기 화 에 필요 한 XML 파일 을 설정 합 니 다.aop01.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- -->
<bean id="math" class="com.zhangguo.Spring052.aop01.Math"></bean>
<!-- -->
<bean id="advices" class="com.zhangguo.Spring052.aop01.Advices"></bean>
<!-- aop -->
<aop:config proxy-target-class="true">
<!-- -->
<aop:aspect ref="advices">
<!-- -->
<aop:pointcut expression="execution(* com.zhangguo.Spring052.aop01.Math.*(..))" id="pointcut1"/>
<!-- -->
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after method="after" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>
1.5.테스트 코드 Test.java 는 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("aop01.xml");
Math math = ctx.getBean("math", Math.class);
int n1 = 100, n2 = 5;
math.add(n1, n2);
math.sub(n1, n2);
math.mut(n1, n2);
math.div(n1, n2);
}
}
실행 결과:2.주석 설정 AOP 사용
2.1.이전 예제 에서 대 리 된 클래스 Math 를 수정 하고 IOC 스 캔 을 실현 하기 위해 Math 클래스 에@Service 를 주석 하고 bean 을 math 라 고 명명 합 니 다.이전 예제 에서 xml 설정 파일 에 bean 을 추가 한 것 과 같 습 니 다.
package com.zhangguo.Spring052.aop02;
import org.springframework.stereotype.Service;
/**
*
*/
@Service("math")
public class Math{
//
public int add(int n1,int n2){
int result=n1+n2;
System.out.println(n1+"+"+n2+"="+result);
return result;
}
//
public int sub(int n1,int n2){
int result=n1-n2;
System.out.println(n1+"-"+n2+"="+result);
return result;
}
//
public int mut(int n1,int n2){
int result=n1*n2;
System.out.println(n1+"X"+n2+"="+result);
return result;
}
//
public int div(int n1,int n2){
int result=n1/n2;
System.out.println(n1+"/"+n2+"="+result);
return result;
}
}
2.2 알림 류 Advices 를 수정 합 니 다.코드 에 3 개의 주석 이 있 습 니 다.@Component 는 이러한 인 스 턴 스 가 Spring IOC 용기 에 의 해 관 리 될 것 임 을 표시 합 니 다.@Aspect 는 절단면 을 표시 합 니 다.@before 는 before 를 사전 알림 으로 표시 하고 인자 execution 을 통 해 절 점 을 설명 합 니 다.Advices.java 코드 는 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop02;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* ,
*
*/
@Component
@Aspect
public class Advices {
@Before("execution(* com.zhangguo.Spring052.aop02.Math.*(..))")
public void before(JoinPoint jp){
System.out.println("---------- ----------");
System.out.println(jp.getSignature().getName());
}
@After("execution(* com.zhangguo.Spring052.aop02.Math.*(..))")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
}
위의 코드 는 아래 의 설정 과 기본적으로 같다.
<!-- -->
<bean id="advices" class="com.zhangguo.Spring052.aop01.Advices"></bean>
<!-- aop -->
<aop:config proxy-target-class="true">
<!-- -->
<aop:aspect ref="advices">
<!-- -->
<aop:pointcut expression="execution(* com.zhangguo.Spring052.aop01.Math.*(..))" id="pointcut1"/>
<!-- -->
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after method="after" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
2.3.새로 추 가 된 프로필 aop 02.xml 은 IOC 설정 을 바탕 으로 aop:aspectj-autoproxy 노드 를 추 가 했 습 니 다.Spring 프레임 워 크 는 자동 으로 AspectJ 절단면 에 설 치 된 Bean 에 프 록 시 를 만 듭 니 다.proxy-target-class="true"속성 은 프 록 시 대상 이 인터페이스 클래스 가 아 닌 하나의 클래스 임 을 나타 냅 니 다.주로 서로 다른 프 록 시 방식 을 선택 하기 위해 서 입 니 다.
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<context:component-scan base-package="com.zhangguo.Spring052.aop02">
</context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
2.4.테스트 실행 코드 Test.java 는 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("aop02.xml");
Math math = ctx.getBean("math", Math.class);
int n1 = 100, n2 = 5;
math.add(n1, n2);
math.sub(n1, n2);
math.mut(n1, n2);
math.div(n1, n2);
}
}
실행 결과:3.AspectJ 절 점 함수
절 점 함 수 는 정확 한 횡 절 논리 적 위 치 를 찾 을 수 있 습 니 다.앞의 예제 에서 우 리 는 execution(*com.zhangguo.Spring 052.aop 02.Math.*(..)만 사용 한 적 이 있 습 니 다.execution 은 절 점 함수 입 니 다.그러나 이 함 수 는 어떤 방법 으로 한 단계 만 사용 한 적 이 있 습 니 다.만약 에 우리 가 짜 려 는 범위 가 클래스 나 특정한 주해 라면 execution 은 그다지 사용 하기 어렵 습 니 다.사실은 모두 9 개의 절 점 함수 가 있 습 니 다.목적 성 이 다르다.
@AspectJ 는 AspectJ 전문 접점 표현 식 으로 절단면 을 설명 합 니 다.Spring 이 지원 하 는 AspectJ 표현 식 은 네 가지 로 나 눌 수 있 습 니 다.
방법 절 점 함수:목표 클래스 방법 정 보 를 설명 하여 연결 점 을 정의 합 니 다.
방법 매개 변수 접점 함수:목표 클래스 를 설명 하 는 방법 으로 참조 정보 정의 연결 점 에 들 어 갑 니 다.
목표 클래스 접점 함수:목표 클래스 유형 정 보 를 설명 하여 연결 점 을 정의 합 니 다.
프 록 시 클래스 접점 함수:프 록 시 클래스 정 보 를 설명 하여 연결 점 을 정의 합 니 다.
일반적인 AspectJ 표현 식 함수:
각 절 점 함수 의 기능 을 보 여주 기 위해 현재 하나의 클래스 StrUtil 을 추 가 했 습 니 다.클래스 는 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop03;
import org.springframework.stereotype.Component;
@Component("strUtil")
public class StrUtil {
public void show(){
System.out.println("Hello StrUtil!");
}
}
테스트 코드 는 다음 과 같 습 니 다:
package com.zhangguo.Spring052.aop03;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("aop03.xml");
IMath math = ctx.getBean("math", Math.class);
int n1 = 100, n2 = 5;
math.add(n1, n2);
math.sub(n1, n2);
math.mut(n1, n2);
math.div(n1, n2);
StrUtil strUtil=ctx.getBean("strUtil",StrUtil.class);
strUtil.show();
}
}
3.1 절 점 함수 execution,알림 과 절단면 의 정 의 는 다음 과 같다.
package com.zhangguo.Spring052.aop03;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* ,
*
*/
@Component
@Aspect
public class Advices {
@Before("execution(* com.zhangguo.Spring052.aop03.Math.*(..))")
public void before(JoinPoint jp){
System.out.println("---------- ----------");
System.out.println(jp.getSignature().getName());
}
//execution
//com.zhangguo.Spring052.aop03
@After("execution(* com.zhangguo.Spring052.aop03.*.*(..))")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
}
실행 결 과 는 다음 과 같 습 니 다.execution(<수정자 모드>?<유형 모드 되 돌리 기><방법 명 모드>(<매개 변수 모드>)<이상 모드>?)
3.2 절 점 함수 within
//within
//com.zhangguo.Spring052.aop03
@After("within(com.zhangguo.Spring052.aop03.*)")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
3.3,this 절 점 함수
//this
// IMath
@After("this(com.zhangguo.Spring052.aop03.IMath)")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
3.4 args 접점 함수
//args
// int
@After("args(int,int)")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
매개 변수 형식 이 기본 데이터 형식 이 아니라면 패키지 이름 이 필요 합 니 다.
3.5,@annotation 절 점 함수
방법 에 주석 을 달 수 있 는 주석 을 먼저 사용자 정의 합 니 다.
package com.zhangguo.Spring052.aop03;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnno {
}
//@annotation
// com.zhangguo.Spring052.aop03.MyAnno
@After("@annotation(com.zhangguo.Spring052.aop03.MyAnno)")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
package com.zhangguo.Spring052.aop03;
import org.springframework.stereotype.Component;
@Component("strUtil")
public class StrUtil {
@MyAnno
public void show(){
System.out.println("Hello StrUtil!");
}
}
실행 결과:다른 테이프@의 절 점 함 수 는 모두 주 해 를 겨냥 한 것 이다
4.AspectJ 알림 주해
AspectJ 알림 주 해 는 모두 6 개 로 5 개 를 자주 사용 하 며 소개 가 적 습 니 다.
먼저 접점 재 활용 문 제 를 해결 합 니 다.다음 코드 에서 보 듯 이 접점 함수 의 내용 은 똑 같 습 니 다.
package com.zhangguo.Spring052.aop04;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* ,
*
*/
@Component
@Aspect
public class Advices {
@Before("execution(* com.zhangguo.Spring052.aop04.Math.*(..))")
public void before(JoinPoint jp){
System.out.println("---------- ----------");
System.out.println(jp.getSignature().getName());
}
@After("execution(* com.zhangguo.Spring052.aop04.Math.*(..))")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
}
먼저 절 점 을 정의 한 다음 에 다시 사용 할 수 있 습 니 다.다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop04;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* ,
*/
@Component
@Aspect
public class Advices {
//
@Pointcut("execution(* com.zhangguo.Spring052.aop04.Math.*(..))")
public void pointcut(){
}
@Before("pointcut()")
public void before(JoinPoint jp){
System.out.println("---------- ----------");
System.out.println(jp.getSignature().getName());
}
@After("pointcut()")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
}
Advices.java 파일 을 수정 하고 다음 과 같은 알림 형식 을 추가 합 니 다.
package com.zhangguo.Spring052.aop04;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* ,
*/
@Component
@Aspect
public class Advices {
//
@Pointcut("execution(* com.zhangguo.Spring052.aop04.Math.a*(..))")
public void pointcut(){
}
//
@Before("pointcut()")
public void before(JoinPoint jp){
System.out.println(jp.getSignature().getName());
System.out.println("---------- ----------");
}
//
@After("pointcut()")
public void after(JoinPoint jp){
System.out.println("---------- ----------");
}
//
@Around("execution(* com.zhangguo.Spring052.aop04.Math.s*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println(pjp.getSignature().getName());
System.out.println("---------- ----------");
Object result=pjp.proceed();
System.out.println("---------- ----------");
return result;
}
//
@AfterReturning(pointcut="execution(* com.zhangguo.Spring052.aop04.Math.m*(..))",returning="result")
public void afterReturning(JoinPoint jp,Object result){
System.out.println(jp.getSignature().getName());
System.out.println(" :"+result);
System.out.println("---------- ----------");
}
//
@AfterThrowing(pointcut="execution(* com.zhangguo.Spring052.aop04.Math.d*(..))",throwing="exp")
public void afterThrowing(JoinPoint jp,Exception exp){
System.out.println(jp.getSignature().getName());
System.out.println(" :"+exp.getMessage());
System.out.println("---------- ----------");
}
}
실행 결과:5.제로 설정 은 Spring IoC 와 AOP 를 실현 합 니 다.
0 설정 을 실현 하기 위해 기 존의 예 시 를 바탕 으로 사용자 클래스 를 추가 합 니 다.다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop05;
public class User {
public void show(){
System.out.println(" ");
}
}
이 종 류 는 주석 이 없어 서 용기 가 자동 으로 관리 되 지 않 는 다.xml 프로필 이 없 기 때문에 설정 정보 로 사용 합 니 다.ApplicationCfg.java 파일 은 다음 과 같 습 니 다.
package com.zhangguo.Spring052.aop05;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration // , <beans/>
@ComponentScan(basePackages="com.zhangguo.Spring052.aop05") // , xml <context:component-scan/>
@EnableAspectJAutoProxy(proxyTargetClass=true) // , <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
public class ApplicationCfg {
// bean, <bean id=getUser class="com.zhangguo.Spring052.aop05.User"/>
@Bean
public User getUser(){
return new User();
}
}
이 종류의 모든 내용 은 기본적으로 xml 설정 과 일대일 관계 가 있 습 니 다.설명 을 보십시오.이렇게 하면 xml 를 쓰 는 것 보다 편리 하지만 발표 후 수정 하기 가 불편 합 니 다.테스트 코드 는 다음 과 같 습 니 다:
package com.zhangguo.Spring052.aop05;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//
ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationCfg.class);
Math math = ctx.getBean("math", Math.class);
int n1 = 100, n2 = 0;
math.add(n1, n2);
math.sub(n1, n2);
math.mut(n1, n2);
try {
math.div(n1, n2);
} catch (Exception e) {
}
User user=ctx.getBean("getUser",User.class);
user.show();
}
}
advices.java 와 같이 아무런 변화 가 없습니다.실행 결 과 는 다음 과 같 습 니 다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.