프로그래밍 안드로이드의 AOP 개발

I. 서론 :

AOP (aspect 지향 프로그래밍, Aspect 지향적 인 프로그래밍) OOP (객체 지향는 프로그래밍, 객체 지향 프로그래밍) 보충과 완벽한이라고 할 수있다. AOP는 "교차"기술로서 알려진 기술을 사용하여, 내부 단면 객체를 디 캡슐화하고, 즉, 재사용 복수의 모듈에 캡슐화 공용 클래스의 동작에 영향을 미치는, 명칭이 "화면"것과, 측면. 소위 "존중"간단히 말해서,이 사업과 그 관련이 있지만, 논리적 또는 책임 비즈니스 모듈로 함께 시스템을 줄이고 모듈 간의 결합의 정도를 줄이고, 미래를 수 있습니다 촉진하기 위해 코드를 복제 쉽게, 캡슐화라는 운용성 및 유지. 정적 하나의 방법으로 짠 안드로이드 관련 AOP 일반적으로 사용되는 방법의 JNI 후크 및 정적 직물, 종이, AspectJ의 사용을 설명합니다. (컴파일시에 제직, 특별 자바 컴파일러를 필요로 바이트 코드의 형태로 대상 바이트 코드 파일을 직접 컴파일러 섹션을 참조하십시오.)

시나리오 둘째, 사용

또한 더 광범위 안드로이드 동안 백엔드를 들어 자바는 안드로이드 자바 (모두, 가장 일반적인 시나리오는 사용자 권한, 매개 변수 유효성 검사, 트랜잭션 처리, 캐시 등을 확인해야 로깅 동일하게 적용 ) 예를 들어, 사용자가 로그인 결정, 권한이 적용 확인 네트워크 상태를 확인하고, 그래서 필터링 중복 클릭에, 당신은 당신이 프로젝트의 실제 요구 일부 비즈니스 시나리오를 기반으로 필요한 사용자 정의 할 수 있습니다, 공통 로그입니다.

셋째, 연습

(1) 의존성을 추가
apply plugin: 'android-aspectjx'

dependencies {
    ...
    compile 'org.aspectj:aspectjrt:1.8.9'
}
复制代码

프로젝트 Gradle을 스크립트 디렉토리와 결합

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        //此处推荐该库,由沪江出品,可免去配置各种复杂任务
        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4'
    }
}
复制代码
2, AOP 주석 및 사용
@Aspect:声明切面,标记类
@Pointcut(切点表达式):定义切点,标记方法
@Before(切点表达式):前置通知,切点之前执行
@Around(切点表达式):环绕通知,切点前后执行
@After(切点表达式):后置通知,切点之后执行
@AfterReturning(切点表达式):返回通知,切点方法返回结果之后执行
@AfterThrowing(切点表达式):异常通知,切点抛出异常时执行
复制代码

표현의 접선 지점의 예 :

如:execution(@com.xxx.aop.TimeLog *.(..))
切点表达式的组成:
execution(@注解 访问权限 返回值的类型 包名.函数名(参数))
复制代码

간단한 간단한 예는 두 가지를 다음과 같습니다 :

@Before("execution(@com.xxx.aop.activity * *(..))")
public void before(JoinPoint point) {
    Log.i(TAG, "method excute before...");
}
匹配activity包下的所有方法,在方法执行前输出日志
复制代码
@Around("execution(@cn.com.xxx.Async * *(..))")
public void doAsyncMethod(ProceedingJoinPoint joinPoint) {
    Log.i(TAG, "method excute before...");
    joinPoint.proceed();
    Log.i(TAG, "method excute after...");
}
匹配带有Async注解的方法,在方法执行前后分别输出日志
复制代码
@Around("execution(@cn.com.xxx.Async * *(..)) && @annotation(async)")
public void doAsyncMethod(ProceedingJoinPoint joinPoint, Async async) {
    Log.i(TAG, "value>>>>>"+async.value());
    <!--to do somethings-->
    joinPoint.proceed();
    <!--to do somethings-->
}
//注意:@annotation(xxx)必须与下面的的参数值对应
匹配带有Async注解的方法,并获取注解中的值,去做相应处理。
复制代码
3, 실용적인 응용 프로그램
장면은 코멘트를 달성하기 위해 캐싱을 사용

1. 다음과 같이 캐시 메모를 정의합니다 :

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

    String key(); //缓存的key

    int expiry() default -1; // 过期时间,单位是秒
}
复制代码

2, 화면을 달성 쓰기

@Aspect
public class CacheAspect {
    private static final String POINTCUT_METHOD = "execution(@cn.com.xxx.annotation.Cache * *(..))";

    @Pointcut(POINTCUT_METHOD)
    public void onCacheMethod() {
    }

    @Around("onCacheMethod() && @annotation(cache)")
    public Object doCacheMethod(ProceedingJoinPoint joinPoint, Cache cache) throws Throwable {
        //获取注解中的key
        String key = cache.key();
        //获取注解中的过期时间
        int expiry = cache.expiry();
        //执行当前注解的方法(放行)
        Object result = joinPoint.proceed();
        //方法执行后进行缓存(缓存对象必须是方法返回值)
        ACache aCache = ACache.get(AopArms.getContext());
        if (expiry>0) {
            aCache.put(key,(Serializable)result,expiry);
        } else {
            aCache.put(key,(Serializable)result);
        }
        return result;
    }
}
复制代码

여기에 참조 ACache에게 만 Acache 파일을 프로젝트 캐시 구현을, 개인적으로는 물론, 당신이 달성하기 위해 갈 수있는, 아주 쉽게 사용할 생각합니다. (3) 시험

    public static void main(String[] args) {
        initData();
        getUser();
    }
    
    //缓存数据
    @Cache(key = "userList")
    private ArrayList<User> initData() {
        ArrayList<User> list = new ArrayList<>();
        for (int i=0; i<5; i++){
            User user = new User();
            user.setName("艾神一不小心:"+i);
            user.setPassword("密码:"+i);
            list.add(user);
        }
        return list;
    }
    
    //获取缓存
    private void getUser() {
        ArrayList<User> users = ACache.get(this).getAsList("userList", User.class);
        Log.e(TAG, "getUser: "+users);
    }
    
复制代码
장면 두, 주석의 사용이 제거 캐시에 저장하는 구현할

다음과 같이 1, 주석 CacheEvict 정의 :

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

    //需要移除的key
    String key();

    // 缓存的清除是否在方法之前执行, 默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
    boolean beforeInvocation() default false;
    
    //是否清空所有缓存
    boolean allEntries() default false;
}
复制代码

2, 화면을 달성 쓰기

@Aspect
public class CacheEvictAspect {
    private static final String POINTCUT_METHOD = "execution(@cn.com.xxx.annotation.CacheEvict * *(..))";

    //切点位置,所有的CacheEvict处
    @Pointcut(POINTCUT_METHOD)
    public void onCacheEvictMethod() {
    }
    
    //环绕处理,并拿到CacheEvict注解值
    @Around("onCacheEvictMethod() && @annotation(cacheEvict)")
    public Object doCacheEvictMethod(ProceedingJoinPoint joinPoint, CacheEvict cacheEvict) throws Throwable {
        String key = cacheEvict.key();
        boolean beforeInvocation = cacheEvict.beforeInvocation();
        boolean allEntries = cacheEvict.allEntries();
        ACache aCache = ACache.get(AopArms.getContext());
        Object result = null;
        if (allEntries){
            //如果是全部清空,则key不需要有值
            if (!TextUtils.isEmpty(key))
                throw new IllegalArgumentException("Key cannot have value when cleaning all caches");
            aCache.clear();
        }
        if (beforeInvocation){
            //方法执行前,移除缓存
            aCache.remove(key);
            result = joinPoint.proceed();
        }else {
            //方法执行后,移除缓存,如果出现异常缓存就不会清除(推荐)
            result = joinPoint.proceed();
            aCache.remove(key);
        }
        return result;
    }
}
复制代码

(3) 시험

public static void main(String[] args) {
        removeUser();
        getUser();
    }
    
    //移除缓存数据
    @CacheEvict(key = "userList")
    private void removeUser() {
        Log.e(TAG, "removeUser: >>>>");
    }
    
    //获取缓存
    private void getUser() {
        ArrayList<User> users = ACache.get(this).getAsList("userList", User.class);
        Log.e(TAG, "getUser: "+users);
    }
复制代码

우리는 결과를 볼 수 있습니다 :

마지막으로 나는 코멘트 AOP 프레임 워크를 기반으로 추천을 썼다 AopArms , 사용 및 간단한 참조 안드로이드 기반의 주석 AOP 프레임 워크 , 일반적으로 안드로이드 개발자 로깅, 비동기 처리, 캐싱, SP 등의 주석, 세트의 제조에 사용되는, 지연 동작, 일반 작업 메커니즘을 재 시도는 시도 - 캐치 등 안전 장치, 여과 자주 클릭, 가입 더 많은 후속 더 강력한 주석 기능이있을 것, 별을 환영했다.

HTTPS : //juejin.im/post/5ce749b6f265da1bba58de15 재현

추천

출처blog.csdn.net/weixin_34015566/article/details/91460165