을 많이 절약 할 수, 당신은 이미 반사를 사용하는 경우 대규모 어쨌든 - 이 코드는 코드를 리팩터링하지 않는 핑계가 아니며 계속 그렇게하기를 원합니다. 사실 더 난잡하게 만들려면 실제로 AspectJ가 필요하지 않습니다. 이처럼 다만 수
도우미 클래스를 반사 필드 액세스 :
package de.scrum_master.app;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
public class FieldHelper {
public static Field getField(Class<?> clazz, String fieldName) {
Field field;
try {
field = clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException("Reflection problem", e);
}
field.setAccessible(true);
return field;
}
public static Field[] getFields(Class<?> clazz) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields)
field.setAccessible(true);
return fields;
}
public static List<String> extractIgnoredFieldsList(Class<?> clazz, String fieldName) {
return Arrays.asList(
getField(clazz, fieldName)
.getAnnotation(IgnoreFields.class)
.fieldNames()
);
}
}
마커 주석 : 호출하는 방법
package de.scrum_master.app;
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.FIELD)
public @interface IgnoreFields {
public String[] fieldNames();
}
클래스 :
package de.scrum_master.app;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import static de.scrum_master.app.FieldHelper.*;
public class A {
int number = 11;
String text = "Hi there!";
Date date = new Date();
String optionalText = "I am not really always needed";
int optionalNumber = 123;
public void doSomething(List<String> ignoredFields) {
for (Field field : getFields(this.getClass())) {
if (!ignoredFields.contains(field.getName())) {
try {
System.out.println(field.getName() + " = " + field.get(this));
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("Reflection problem", e);
}
}
}
}
}
주석 멤버 필드와
등급 :
package de.scrum_master.app;
import static de.scrum_master.app.FieldHelper.*;
public class B {
@IgnoreFields(fieldNames = { "optionalText", "optionalNumber" })
A noOptionalsA = new A();
@IgnoreFields(fieldNames = { "text", "number", "date" })
A onlyOptionalsA = new A();
public static void main(String[] args) {
B b = new B();
b.noOptionalsA.doSomething(extractIgnoredFieldsList(b.getClass(), "noOptionalsA"));
System.out.println("----------------------------------------");
b.onlyOptionalsA.doSomething(extractIgnoredFieldsList(b.getClass(), "onlyOptionalsA"));
}
}
콘솔 로그 :
number = 11
text = Hi there!
date = Wed Dec 27 18:54:44 ICT 2017
----------------------------------------
optionalText = I am not really always needed
optionalNumber = 123
당신은, 제발 여기 일어나고 또는 여전히 AspectJ를 용액에 고집 무엇인지 이해하지 않는 경우 알려 주시면 추가적인 aspect 코드를 설명하고 설명해 드리겠습니다.
내가 대답하기 전에 당신이 분명히 말하기를 바란다 : "조언에서 메소드'b()'로 데이터를 전송한다는 것은 무엇을 의미합니까? (의사) 코드를 편집하고 해당 데이터를 해당 방법에서 사용하는 방법을 알려주십시오. BTW,'A' 필드와 그 필드에 할당 된 객체의 연결과 관련하여 수동으로 부기를 할 준비가 되셨습니까? 이것이 이것이 취할 수있는 일이기 때문에 가능하지만 응용 프로그램 설계로 인해 약간 지루합니다. – kriegaex
내 의사 코드를 업데이트했습니다. 주요 아이디어는 주석 값에 나열된 필드 이름 목록을 메서드 b()에 전달하여이 메서드 실행 중에이 필드가 무시되도록하는 것입니다. –
'new B(). fieldA.b()'(BTW, 거기에 괄호를 잊어 버렸습니다.) 메소드 서명'void b (String [] fieldsToIgnore)'와 일치 할 수 없으므로 컴파일되지 않습니다. 이것은 AspectJ를 사용하기 전에도 자바 문제이다.또한 응용 프로그램이 (a) 응용 프로그램이 측면에 대해 알고 있고 그 응용 프로그램 없이는 작업 할 수없는 경우와 (b) 주석이 문자열로 주석에 나열된 필드 이름을 너무 많이 필요로하는 경우에만 응용 프로그램 디자인에 결함이있는 것입니다. 리팩토링되면 깨질 것입니다. 이것은 교차 관심사가 아니므로 가능한 경우 AOP 유스 케이스가 없습니다. – kriegaex