注釈認証
問題の説明
権限認証
権限認証はずっと複雑な問題であり,実験という要求が厳しくない製品であれば,権限認証を直接逃れる.
ソフトウェアの设计とプログラミングの実践の実験、バックグラウンドは直接
ビジネスプロジェクトでは、権限がないとだめです.
注釈
権限については、良い解決策が見つからなかった.ネット上でプロジェクトを検査するまで、機能が簡単で、ユーザーの役割が単一であるため、潘先生は注釈を利用して権限認証を実現する案を提出した.
2つの注釈,
サンプルコード
サンプルコードアドレス:auth-annotation-mengyunzhi
開発環境:
ブロッキング
3つの方法に従って、ユーザ権限をブロックし、ブロック+
ブロッカーは、
ブロッキングが完了したら、リクエストメソッドを実行します.
区別する
このように見ると、ブロックは
最近デザインモードのエージェントモードを学びました.
ブロッキング
ブロッキングを宣言します.3番目のパラメータは、現在ブロックされている方法です.
基本的な考え方
現在のメソッドに
パフォーマンスの最適化
はんしゃ
要求されるたびに、ブロッキングを実行し、
このメソッドはまた
この方法は、
あまり話さないで、反射して、性能の問題があります!
個人的な理解
同様に
以前
これは外国の反射に関する文章です.反射はいったいどれだけ遅いですか.How Slow is Reflection in Android?
ユーザがアプリケーションの起動時間を期待する平均値は
Data-Binding
顔を殴る?
なお、
作成したコードに直接基づいてオリジナル
ソリューション
ブロッキングで反射を使用する性能の問題を解決するために、
その後、ブロックごとにメモリから直接読み取り、パフォーマンスを向上させます.
コンテナ起動イベントをリスニングし、コンテナ起動時に以下のコードを実行し、すべてのコントローラとそのメソッドの注釈をスキャンし、条件に合致する場合は
ブロッキングの変更
元のブロッキングはこうでした.
今はこうです.
以前は2回反射していましたが、現在は
この2つの実装を見てみましょう.
いずれも
注記の注記
今は注釈が少ないので、私たちは2行書いて、問題は大きくないと思います.
後で認証注釈が多くなったら?
このように,現在の方法がブロックされるか否かを判定する汎用的な注釈があり,
注釈の作成
注釈に注釈を付ける
解析注記
注釈を付けるのは簡単で、どのように注釈を解析するかが重要です.
反射パケット内の
例:
どのようにして注釈の注釈を取得しますか?
午前中探して、私がこの問題を解決するのはやはり一定の運に頼っていると言わざるを得ません.私が諦めようとしたとき、
ドキュメントを簡単に開く:Class AnnotationUtils-Spring Core Docs
4つ目の方法は私が望んでいることです
このツールクラスを使用すると、メソッドに注記が表示されている注記を直接取得できます.
この方法は、
最終コード:
まとめ
問題を解決する新しい方法を学びました.あるフレームワークもあなたが直面した問題に遭遇したことがあるはずです.フレームワークのツールクラスを探してみると、役に立つかもしれません.
権限認証
権限認証はずっと複雑な問題であり,実験という要求が厳しくない製品であれば,権限認証を直接逃れる.
ソフトウェアの设计とプログラミングの実践の実験、バックグラウンドは直接
Spring Data REST
を使って、使いやすいのは使いやすいですが、実际のプロジェクトの中で运用することができなくて、直接api
を自动的に生成して、谁が呼び出してもいいです.ビジネスプロジェクトでは、権限がないとだめです.
注釈
権限については、良い解決策が見つからなかった.ネット上でプロジェクトを検査するまで、機能が簡単で、ユーザーの役割が単一であるため、潘先生は注釈を利用して権限認証を実現する案を提出した.
2つの注釈,
AdminOnly
注釈は管理者にしか使用できない方法,Anonymous
注釈は対外的に認証を必要としないインタフェースであり,その他の非注釈は一般ユーザーに使用される.サンプルコード
サンプルコードアドレス:auth-annotation-mengyunzhi
開発環境:
Java 1.8
+Spring Boot 2.1.2.RELEASE
インプリメンテーションブロッキング
3つの方法に従って、ユーザ権限をブロックし、ブロック+
AOP
のモードを使用して実現する.ブロッカーは、
AdminOnly
およびAnonymous
注記のないメソッド要求をブロックし、ユーザ認証を行う.ブロッキングが完了したら、リクエストメソッドを実行します.
AOP
切AdminOnly
注釈の前置き通知は、管理者が認証した切面論理を植え込む.Anonymous
注釈に対しては何の処理も行わず,匿名ユーザへのアクセスを実現した.区別する
このように見ると、ブロックは
AOP
に似ています.それは私たちのこの例がまだAOP
の実際の価値を発揮していないからです.AOP
この例よりずっと強いように見えます.最近デザインモードのエージェントモードを学びました.
AOP
と密接に関係しています.これからの文章で皆さんと一緒に勉強します.ブロッキング
ブロッキングを宣言します.3番目のパラメータは、現在ブロックされている方法です.
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
}
基本的な考え方
現在のメソッドに
AdminOnly
とAnonymous
の注記が表示されているかどうかを反射で取得し、なければ一般ユーザ認証を行う.AdminOnly adminOnly = handlerMethod.getMethodAnnotation(AdminOnly.class);
Anonymous anonymous = handlerMethod.getMethodAnnotation(Anonymous.class);
if (adminOnly != null && anonymous != null) {
return true;
}
boolean result = false;
//
return result;
パフォーマンスの最適化
はんしゃ
要求されるたびに、ブロッキングを実行し、
getMethodAnnotation
メソッドを呼び出します.getMethodAnnotation
メソッドのソースコード実装を見てみましょう.org.springframework.web.method.HandlerMethod
のgetMethodAnnotation
メソッド:@Nullable
public A getMethodAnnotation(ClassannotationType) {
return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType);
}
このメソッドはまた
AnnotatedElementUtils.findMergedAnnotation
メソッドを呼び出し、さらにクリックしてみましょう.org.springframework.core.annotation.AnnotatedElementUtils
のfindMergedAnnotation
実装:@Nullable
public static A findMergedAnnotation(AnnotatedElement element, ClassannotationType) {
// Shortcut: directly present on the element, with no merging needed?
A annotation = element.getDeclaredAnnotation(annotationType);
if (annotation != null) {
return AnnotationUtils.synthesizeAnnotation(annotation, element);
}
// Exhaustive retrieval of merged annotation attributes...
AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationType, false, false);
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
}
この方法は、
AnnotatedElement
インタフェースで宣言されたgetDeclaredAnnotation
メソッドを呼び出して注釈取得を行う.AnnotatedElement
インタフェース、java
反射パケットに存在する:あまり話さないで、反射して、性能の問題があります!
個人的な理解
同様に
Java
であり、Google
がAndroid
に対して反射する態度を見ればよい.以前
Google Android
の公式サイトに行ったことがあるのを覚えていますが、公式にはAndroid
でフレームを使用することをお勧めしていません.これは深刻な性能問題をもたらす可能性があります.その中には、従来のJava
フレームで大量に使用されている反射を考慮しています.これは外国の反射に関する文章です.反射はいったいどれだけ遅いですか.How Slow is Reflection in Android?
ユーザがアプリケーションの起動時間を期待する平均値は
2s
であるという仕様について述べた.NYTimes Android App
でGoogle
のGson
を使用してデータ解析を行います.これは私たちのバックグラウンドで広く使用されています.アリのfastjson
と並んで、非常に人気のあるjson
ライブラリです.NYTimes
のエンジニアは、Gson
で反射を使用してデータ型を取得することを発見し、アプリケーションの起動時に約700ms
の遅延が増加した.ActiveAndroid
は反射を使って実現されたライブラリで、わざわざGithub
をぶらぶらして、4000
多star
は、かなり流行しているオープンソースプロジェクトです!Scribd
: 1093ms for call com.activeandroid.ActiveAndroid.initialize
. Myntra
: 1421ms for call com.activeandroid.ActiveAndroid.initialize
. Data-Binding
顔を殴る?
Android
フレームワークの使用はお勧めしないのではないでしょうか.では、なぜGoogle
がまたData-Binding
を発売したのでしょうか.なお、
Google
は、サードパーティ製フレームワークの高コストによるパフォーマンスの問題を考慮している.Data-Binding
の利点を見てみると、最も重要なのは、フレームワークが反射を使用しないことであり、ダイナミックコード生成技術を使用して、フレームワークを使用することによって性能の問題が発生しないことです.作成したコードに直接基づいてオリジナル
Android
のコードを生成するので、パフォーマンスの問題はありません.ソリューション
ブロッキングで反射を使用する性能の問題を解決するために、
SpringBoot
の設計構想を学び、起動時にすべての反射注釈の読み取りを直接完了し、メモリに格納します.その後、ブロックごとにメモリから直接読み取り、パフォーマンスを向上させます.
コンテナ起動イベントをリスニングし、コンテナ起動時に以下のコードを実行し、すべてのコントローラとそのメソッドの注釈をスキャンし、条件に合致する場合は
HashMap
に配置します.// Scanner, filter
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
// , RestController
scanner.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
//
for (BeanDefinition beanDefinition : scanner.findCandidateComponents(basePackageName)) {
//
String name = beanDefinition.getBeanClassName();
try {
//
Class> clazz = Class.forName(name);
// List
List methodNameList = new ArrayList<>();
// ( , )
for (Method method : clazz.getDeclaredMethods()) {
//
AdminOnly adminOnly = method.getAnnotation(AdminOnly.class);
Anonymous anonymous = method.getAnnotation(Anonymous.class);
// AdminOnly Anonymous
if (adminOnly == null && anonymous == null) {
// List
methodNameList.add(method.getName());
}
}
// Map
AuthAnnotationConfig.getAnnotationsMap().put(clazz, methodNameList);
} catch (ClassNotFoundException e) {
logger.error(" , ClassNotFoundException ");
}
}
ブロッキングの変更
元のブロッキングはこうでした.
AdminOnly adminOnly = handlerMethod.getMethodAnnotation(AdminOnly.class);
Anonymous anonymous = handlerMethod.getMethodAnnotation(Anonymous.class);
if (adminOnly != null && anonymous != null) {
return true;
}
boolean result = false;
//
return result;
今はこうです.
logger.debug(" ");
Class> clazz = handlerMethod.getBeanType();
logger.debug(" ");
String methodName = handlerMethod.getMethod().getName();
logger.debug(" ");
List authMethodNames = AuthAnnotationConfig.getAnnotationsMap().get(clazz);
logger.debug(" List , ");
if (authMethodNames == null || !authMethodNames.contains(methodName)) {
return true;
}
logger.debug(" ");
boolean result = false;
//
return result;
以前は2回反射していましたが、現在は
handlerMethod.getBeanType()
とhandlerMethod.getMethod().getName()
が呼び出されています.この2つの実装を見てみましょう.
getBeanType
public Class> getBeanType() {
return this.beanType;
}
getMethod
public Method getMethod() {
return this.method;
}
いずれも
org.springframework.web.method.HandlerMethod
クラスで直接属性を返し,このHandlerMethod
はSpring
コンテナ起動時に既に構築されたメソッドオブジェクトであり,ブロッキング実行中に反射を呼び出さなかったと推定した.注記の注記
今は注釈が少ないので、私たちは2行書いて、問題は大きくないと思います.
//
AdminOnly adminOnly = method.getAnnotation(AdminOnly.class);
Anonymous anonymous = method.getAnnotation(Anonymous.class);
後で認証注釈が多くなったら?
このように,現在の方法がブロックされるか否かを判定する汎用的な注釈があり,
AdminOnly
およびAnonymous
はその注釈の機能を継承すべきであり,これにより,後でブロックにブロックされない注釈を追加したい場合に,起動時のスキャン方法を修正する必要がなくなることを期待する.//
AdminAuth adminAuth = method.getAnnotation(AdminAuth.class);
Spring Boot
のように,注釈に注釈を加え,複合注釈を実現することを期待する.@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
}
注釈の作成
Java
カスタム注釈が分からない場合は、慕課網に行って関連課程を学ぶことができます:Java注釈-慕課網を全面的に解析します@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AdminAuth {
}
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
,この注釈は方法に表記してもよいし、他の注釈に表記してもよい.@Retention(RetentionPolicy.RUNTIME)
,この注記は、プログラムの実行中まで保持される.注釈に注釈を付ける
AdminOnly:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@AdminAuth
public @interface AdminOnly {
}
Anonymous:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@AdminAuth
public @interface Anonymous {
}
解析注記
注釈を付けるのは簡単で、どのように注釈を解析するかが重要です.
反射パケット内の
Method
クラスが提供するgetAnnotation
メソッドを呼び出すと、現在表示されている注釈のみが表示されます.例:
@AdminOnly
public void test() {
}
getAnnotation
でAdminOnly
を取得できますが、@AdminOnly
に注記されている@AdminAuth
の注記は取得されません.どのようにして注釈の注釈を取得しますか?
午前中探して、私がこの問題を解決するのはやはり一定の運に頼っていると言わざるを得ません.私が諦めようとしたとき、
Google
でSpringFramework
の注釈ツール類AnnotationUtils
が見つかりました.ドキュメントを簡単に開く:Class AnnotationUtils-Spring Core Docs
4つ目の方法は私が望んでいることです
このツールクラスを使用すると、メソッドに注記が表示されている注記を直接取得できます.
@AdminOnly
public void test() {
}
AdminAuth adminAuth = AnnotationUtils.getAnnotation(method, AdminAuth.class);
この方法は、
test
メソッドで継承された@AdminAuth
注釈を取得することができる.最終コード:
@Component
public class InitAnnotationsConfig implements ApplicationListener {
//
private static final String basePackageName = "com.mengyunzhi.checkApplyOnline";
//
private static final Logger logger = LoggerFactory.getLogger(InitAnnotationsConfig.class);
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// Scanner, filter
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
// , RestController
scanner.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
//
for (BeanDefinition beanDefinition : scanner.findCandidateComponents(basePackageName)) {
//
String name = beanDefinition.getBeanClassName();
try {
//
Class> clazz = Class.forName(name);
// List
List methodNameList = new ArrayList<>();
// ( , )
for (Method method : clazz.getDeclaredMethods()) {
//
AdminAuth adminAuth = AnnotationUtils.getAnnotation(method, AdminAuth.class);
// ,
if (adminAuth == null) {
// List
methodNameList.add(method.getName());
}
}
// Map
AuthAnnotationConfig.getAnnotationsMap().put(clazz, methodNameList);
} catch (ClassNotFoundException e) {
logger.error(" , ClassNotFoundException ");
}
}
}
}
まとめ
問題を解決する新しい方法を学びました.あるフレームワークもあなたが直面した問題に遭遇したことがあるはずです.フレームワークのツールクラスを探してみると、役に立つかもしれません.