Spring AOP 기본 읽기/쓰기 분리

깊은 토론은 왜 읽기와 쓰기를 분리해야 합니까?
서버를 위해 더 많은 사용자를 불러옵니까?사이트의 응답 속도를 높였습니까?데이터베이스 서버의 압력을 분담합니까?이중 핫 스페어를 위해 백업 서버를 낭비하고 싶지 않으십니까?위의 이 대답들은 모두 틀린 것이 아니라고 생각하지만, 완전히 정확한 것은 아니다.'읽기와 쓰기 분리'는 그다지 신기한 것이 아니며, 얼마나 큰 성능 향상도 가져오지 못한다. 아마도 더 많은 작용은 데이터 안전한 백업일 것이다.
하나의 라이브러리에서 읽기와 쓰기로 분리되는 것은 이론적으로 서버의 압력에 있어 두 배의 성능 향상을 가져올 수 있지만, 당신의 응용 서버는 정말 이 배의 향상이 필요합니까?차라리 서버에서Memcached, Redis 같은 분포식 캐시를 사용해 보세요. 그 성능은 몇 십 배나 향상될 수 있습니다.그리고 서버 하드웨어가 매우 강하고 성능이 저렴한 오늘날에는 전혀 필요없다. 그래서 오늘날에는 데이터 안전을 위해 설계하는 것이 더 많은 직책이고 성능을 향상시키는 것이 좋다고 생각한다.
아마도 우리는 더욱 라고 불러야 할 것이다.
AOP를 이용한 읽기와 쓰기 분리
읽기와 쓰기 분리 방식은 매우 간단하다. 바로 당신이 데이터를 읽을 때 라이브러리에 연결하고 데이터를 쓸 때 메인 라이브러리에 연결한다. 구체적인 코드 실현은 당연히 연결할 때 조작하는 것이다. 이것은 어렵지 않다. 코드에 쓰면 된다.그러나 추구하는 프로그램원들은 모두 이렇게 문제를 해결하는 것이 아니냐!
사실 전편Spring AOP 차단기의 기본 구현을 통해 우리는 AOP가 방법이 실행되기 전에 우리가 원하는 코드를 삽입하여 실행할 수 있다는 것을 알고 있다. 그러면 우리는 데이터베이스 조작을 실행하기 전에 업무에 따라 데이터 원본을 동적 전환할 수 있지 않겠는가?
이 방식을 생각해 보면 이론적으로 가능한 것 같다. 이런 방식은 우선 업무 코드에서 전환할 필요가 없다. 둘째, 우리가 읽기와 쓰기를 분리할 필요가 없을 수도 있다. AOP에서 전환한 코드를 제거하면 된다. 셋째, 확장성이 좋을 수도 있다.
기다릴 수 없어, 코드 훑기 시작해.
네가 깊이 이해하고 싶다면 내가 너에게 몇 가지 프로그램에서 사용하는 키워드enum( ),annotation( ),JoinPoint( ),AbstractRoutingDataSource( )를 줄게. 너는 이것들을 이해하면 알 수 있다. 사실 너는 어떤 심층적인 것을 깊이 파고들 필요가 없다. 이해하면 된다.
1. JdbcContextHolder 구축.java 클래스

public class JdbcContextHolder {

 private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

 public static void setJdbcType(String jdbcType) {
 contextHolder.set(jdbcType);
 }

 public static void setSlave() {
 setJdbcType("slave");
 }

 public static void setMaster() {
 clearJdbcType();
 }

 public static String getJdbcType() {
 return (String) contextHolder.get();
 }

 public static void clearJdbcType() {
 contextHolder.remove();
 }
}

이 종류의 역할은 데이터 원본 연결을 설정하고 얻는 데 쓰인다
2. 새 DynamicDataSource.java 클래스, AbstractRoutingDataSource 상속

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import cn.mayongfa.common.JdbcContextHolder;

public class DynamicDataSource extends AbstractRoutingDataSource {

 @Override
 protected Object determineCurrentLookupKey() {
 //  
 return JdbcContextHolder.getJdbcType();
 }
}

연구를 통해 우리는 determineCurrentLookupKey 방법이 관련 데이터 원본을 얻는 연결이라는 것을 알았기 때문에 determineCurrentLookupKey 방법을 다시 쓰면 된다. 그리고 우리는 방금 우리가 구축한 JdbcContextHolder 클래스를 통해 얻을 수 있다.그럼 어떻게 설정하지?
3. 데이터 소스 DataSourceType 구축java 매거류

public enum DataSourceType {

 // 
 Master("master"),

 // 
 Slave("slave");

 private DataSourceType(String name) {
 this.name = name;
 }

 private String name;

 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
}

이 매거류의 작용은 사실 데이터 원본을 설정하기 위해 생겨난 것이다. 그 목적은 데이터 원본을 설정할 때 더욱 편리하고 실처럼 매끄럽도록 하는 것이다.
4. 새 DataSource.java Annotation(사용자 정의 메모) 클래스

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;

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD)
@Documented
public @interface DataSource { 

 DataSourceType value() default DataSourceType.Master;

} 

사용자 정의 주석의 의미는 더 이상 토론을 많이 하지 않는다. 한마디로 클래스나 방법명에 라벨을 붙이는 형식으로 이 방법을 다르게 할 수 있다.구체적으로 어떻게 다르냐면, 이것은 너에게 있다.
5. 새 DataSourceChoose.java 데이터베이스 전환 클래스

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import cn.mayongfa.common.JdbcContextHolder;

public class DataSourceChoose {

// 
public void before(JoinPoint point){
 Object target = point.getTarget(); 
 String method = point.getSignature().getName(); 
 Class<?>[] classz = target.getClass().getInterfaces(); 
 MethodSignature methodSignature = (MethodSignature)point.getSignature();
 Class<?>[] parameterTypes = methodSignature.getMethod().getParameterTypes();
 try {
  Method m = classz[0].getMethod(method, parameterTypes); 
  if (m!=null && m.isAnnotationPresent(DataSource.class)) { 
  DataSource data = m.getAnnotation(DataSource.class); 
  JdbcContextHolder.clearJdbcType();
  JdbcContextHolder.setJdbcType(data.value().getName());
  } 
 } catch (Exception e) { 
  // TODO: handle exception 
 } 
}
}

이것은 사실 차단기 종류인데 주요한 역할은 그 방법의 이름에 @DataSource이라는 사용자 정의 주석이 있는 것을 차단하는 것이다. 주해를 얻은 value() 값에 따라 상응하는 데이터 원본 전환을 하는 것이다.
여기까지 전체 읽기와 쓰기가 분리된 분석과 업무 논리와 구체적인 코드가 끝났습니다. 이상은 본고의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 지지해 주십시오.

좋은 웹페이지 즐겨찾기