use*_*545 6 java spring annotations jpa featuretoggle
如何切换java注释功能?
简单的功能切换: - if(启用切换)执行x
Spring允许使用"profiles"来切换bean.
我使用这些并且它们很好,但我想在字段或类上切换注释..我该怎么做?
用例,我有一个有jpa注释的类.我希望能够在某些环境中通过配置标记某些字段是@transient.
可能的选择之一是使用aspectj及其声明注释的能力和spring加载时方面编织的能力。
我认为注释不能有条件地声明,但您始终可以将它们编译在一个单独的 jar 中,该 jar 可以根据特定环境放入类路径中,以便加载时编织器能够找到它。
更新
虽然这里有很多有用的答案,但我发现禁用/启用注释在使用spectj时非常有趣,因此示例如下。
最新版本的aspectj支持删除注释,但目前此功能仅适用于字段注释,因此非常有用的方法是根本不声明注释,如果必须启用它们 - 将带有预编译方面的jar放入其中正如我之前提到的,将启用注释到类路径中。
样本
第一个罐子
主要班级
package org.foo.bar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
MyClass myObj = context.getBean("myObj", MyClass.class);
System.out.println(myObj);
System.out.println(myObj.getValue1());
System.out.println(myObj.getValue2());
}
}
Run Code Online (Sandbox Code Playgroud)
我们将在其中声明注释的类
package org.foo.bar;
public class MyClass {
@MyAnn("annotated-field-1")
private String field1;
private String field2;
@MyAnn("annotated-method-1")
public String getValue1() {
String value = null;
try {
MyAnn ann = getClass().getDeclaredMethod("getValue1").getAnnotation(MyAnn.class);
if(ann != null) {
value = ann.value();
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return value;
}
public String getValue2() {
String value = null;
try {
MyAnn ann = getClass().getDeclaredMethod("getValue2").getAnnotation(MyAnn.class);
if(ann != null) {
value = ann.value();
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return value;
}
@Override
public String toString() {
String field1 = null;
try {
MyAnn ann = getClass().getDeclaredField("field1").getAnnotation(MyAnn.class);
if(ann != null) {
field1 = ann.value();
}
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
String field2 = null;
try {
MyAnn ann = getClass().getDeclaredField("field2").getAnnotation(MyAnn.class);
if(ann != null) {
field2 = ann.value();
}
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
StringBuilder sb = new StringBuilder();
sb.append("MyClass");
sb.append("{field1='").append(field1).append('\'');
sb.append(", field2='").append(field2).append('\'');
sb.append('}');
return sb.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
注释本身
package org.foo.bar;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface MyAnn {
String value();
}
Run Code Online (Sandbox Code Playgroud)
应用上下文
<?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: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-3.1.xsd">
<context:load-time-weaver />
<bean id="myObj" class="org.foo.bar.MyClass" />
</beans>
Run Code Online (Sandbox Code Playgroud)
第二个罐子
方面
package org.foo.bar;
public aspect ToggleAnnotationAspect {
declare @field : private String org.foo.bar.MyClass.field1 : -@MyAnn;
declare @field : private String org.foo.bar.MyClass.field2 : @MyAnn("annotated-field-2");
declare @method : public String org.foo.bar.MyClass.getValue2() : @MyAnn("annotated-method-2");
}
Run Code Online (Sandbox Code Playgroud)
META-INF/aop.xml
<?xml version="1.0"?>
<aspectj>
<aspects>
<aspect name="org.foo.bar.ToggleAnnotationAspect"/>
</aspects>
</aspectj>
Run Code Online (Sandbox Code Playgroud)
在类路径中没有第二个 jar 的情况下运行应用程序
java -javaagent:spring-instrument-3.1.3.RELEASE.jar \
-classpath app1.jar;<rest_of_cp> org.foo.bar.Main
Run Code Online (Sandbox Code Playgroud)
将打印
MyClass{field1='annotated-field-1', field2='null'}
annotated-method-1
null
Run Code Online (Sandbox Code Playgroud)
使用类路径中的第二个 jar 运行应用程序
java -javaagent:spring-instrument-3.1.3.RELEASE.jar \
-classpath app1.jar;app1-aspects.jar;<rest_of_cp> org.foo.bar.Main
Run Code Online (Sandbox Code Playgroud)
将打印
MyClass{field1='null', field2='annotated-field-2'}
annotated-method-1
annotated-method-2
Run Code Online (Sandbox Code Playgroud)
因此根本没有对应用程序源进行任何修改。
归档时间: |
|
查看次数: |
3982 次 |
最近记录: |