Skip to content

Commit

Permalink
Merge pull request #2 from Abel-Huang/feat_support_spring_aop
Browse files Browse the repository at this point in the history
Feat support spring aop
  • Loading branch information
Abel-Huang authored Apr 11, 2024
2 parents 665fb06 + 020b5b8 commit 9207c6e
Show file tree
Hide file tree
Showing 35 changed files with 989 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

* Support IOC(DONE)
* Support Spring Event(DONE)
* Support Spring AOP(TODO)
* Support Spring AOP(DOING)
* Support Annotation Driven(TODO)
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,18 @@
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.21.1</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>

</dependencies>
</project>
17 changes: 17 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/Advisor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cn.abelib.springframework.aop;

import org.aopalliance.aop.Advice;

/**
* @author abel.huang
* @version 1.0
* @date 2024/3/31 下午 10:35
*/
public interface Advisor {

/**
* Return the advice part of this aspect. An advice may be an
* interceptor, a before advice, a throws advice, etc.
*/
Advice getAdvice();
}
14 changes: 14 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/BeforeAdvice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cn.abelib.springframework.aop;

import org.aopalliance.aop.Advice;

/**
* Common marker interface for before advice
*
* @author abel.huang
* @version 1.0
* @date 2024/3/31 下午 10:27
*/
public interface BeforeAdvice extends Advice {

}
17 changes: 17 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/ClassFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cn.abelib.springframework.aop;

/**
* Filter that restricts matching of a pointcut or introduction to
* a given set of target classes.
*
* @author abel.huang
* @version 1.0
* @date 2024/3/19 0:04
*/
public interface ClassFilter {

/**
* Should the pointcut apply to the given interface or target class?
*/
boolean matches(Class<?> clazz);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cn.abelib.springframework.aop;

import java.lang.reflect.Method;

/**
*
* Advice invoked before a method is invoked. Such advices cannot
* prevent the method call proceeding, unless they throw a Throwable.
*
* @author abel.huang
* @version 1.0
* @date 2024/3/31 下午 10:33
*/
public interface MethodBeforeAdvice extends BeforeAdvice {

/**
* Callback before a given method is invoked.
*/
void before(Method method, Object[] args, Object target) throws Throwable;
}
33 changes: 33 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/MethodMatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cn.abelib.springframework.aop;

import java.lang.reflect.Method;

/**
* Part of a {@link Pointcut}: Checks whether the target method is eligible for advice.
*
* @author abel.huang
* @version 1.0
* @date 2024/3/19 0:05
*/
public interface MethodMatcher {

/**
* Perform static checking whether the given method matches. If this
* returns {@code false} or if the {@link #isRuntime()} method
* returns {@code false}, no runtime check (i.e. no.
*/
boolean matches(Method method, Class<?> targetClass);

/**
* Is this MethodMatcher dynamic, that is, must a final call be made on the
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method at
* runtime even if the 2-arg matches method returns {@code true}
*/
boolean isRuntime();

/**
* Check whether there a runtime (dynamic) match for this method,
* which must have matched statically.
*/
boolean matches(Method method, Class<?> targetClass, Object... args);
}
21 changes: 21 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/Pointcut.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cn.abelib.springframework.aop;

/**
* Core Spring pointcut abstraction.
*
* @author abel.huang
* @version 1.0
* @date 2024/3/19 0:03
*/
public interface Pointcut {

/**
* Return the ClassFilter for this pointcut.
*/
ClassFilter getClassFilter();

/**
* Return the MethodMatcher for this pointcut.
*/
MethodMatcher getMethodMatcher();
}
18 changes: 18 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/PointcutAdvisor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cn.abelib.springframework.aop;

/**
* Superinterface for all Advisors that are driven by a pointcut.
* This covers nearly all advisors except introduction advisors,
* for which method-level matching doesn't apply.
*
* @author abel.huang
* @version 1.0
* @date 2024/3/31 下午 10:37
*/
public interface PointcutAdvisor extends Advisor {

/**
* Get the Pointcut that drives this advisor.
*/
Pointcut getPointcut();
}
33 changes: 33 additions & 0 deletions src/main/java/cn/abelib/springframework/aop/TargetSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cn.abelib.springframework.aop;

/**
* @author abel.huang
* @version 1.0
* @date 2024/3/25 23:41
*/
public class TargetSource {

private final Object target;

public TargetSource(Object target) {
this.target = target;
}

/**
* Return the type of targets returned by this {@link TargetSource}.
* <p>Can return <code>null</code>, although certain usages of a
* <code>TargetSource</code> might just work with a predetermined
* target class.
*/
public Class<?>[] getTargetClass(){
return this.target.getClass().getInterfaces();
}

/**
* Return a target instance. Invoked immediately before the
* AOP framework calls the "target" of an AOP method invocation.
*/
public Object getTarget(){
return this.target;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package cn.abelib.springframework.aop.aspectj;

import cn.abelib.springframework.aop.ClassFilter;
import cn.abelib.springframework.aop.MethodMatcher;
import cn.abelib.springframework.aop.Pointcut;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
* @author abel.huang
* @version 1.0
* @date 2024/3/19 22:44
*/
public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {
private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<>();

static {
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
}

private final PointcutExpression pointcutExpression;

public AspectJExpressionPointcut(String expression) {
PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(SUPPORTED_PRIMITIVES, this.getClass().getClassLoader());
pointcutExpression = pointcutParser.parsePointcutExpression(expression);
}

@Override
public boolean matches(Class<?> clazz) {
return pointcutExpression.couldMatchJoinPointsInType(clazz);
}

@Override
public boolean matches(Method method, Class<?> targetClass) {
return pointcutExpression.matchesMethodExecution(method).alwaysMatches();
}

@Override
public boolean isRuntime() {
return this.pointcutExpression.mayNeedDynamicTest();
}

/**
* TODO
* @param method
* @param targetClass
* @param args
* @return
*/
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
return false;
}

@Override
public ClassFilter getClassFilter() {
return this;
}

@Override
public MethodMatcher getMethodMatcher() {
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cn.abelib.springframework.aop.aspectj;

import cn.abelib.springframework.aop.Pointcut;
import cn.abelib.springframework.aop.PointcutAdvisor;
import org.aopalliance.aop.Advice;

/**
* @author abel.huang
* @version 1.0
* @date 2024/3/31 下午 10:38
*/
public class AspectJExpressionPointcutAdvisor implements PointcutAdvisor {

private AspectJExpressionPointcut pointcut;

private Advice advice;

private String expression;

public void setExpression(String expression){
this.expression = expression;
}

public String getExpression() {
return expression;
}

@Override
public Pointcut getPointcut() {
if (null == pointcut) {
pointcut = new AspectJExpressionPointcut(expression);
}
return pointcut;
}

public Advice getAdvice() {
return advice;
}

public void setAdvice(Advice advice){
this.advice = advice;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cn.abelib.springframework.aop.framework;

import cn.abelib.springframework.aop.MethodMatcher;
import cn.abelib.springframework.aop.TargetSource;
import org.aopalliance.intercept.MethodInterceptor;

/**
* @author abel.huang
* @version 1.0
* @date 2024/3/19 22:43
*/
public class AdvisedSupport {
// ProxyConfig
private boolean proxyTargetClass = false;

private TargetSource targetSource;

private MethodInterceptor methodInterceptor;

private MethodMatcher methodMatcher;

public boolean isProxyTargetClass() {
return proxyTargetClass;
}

public void setProxyTargetClass(boolean proxyTargetClass) {
this.proxyTargetClass = proxyTargetClass;
}

public TargetSource getTargetSource() {
return targetSource;
}

public void setTargetSource(TargetSource targetSource) {
this.targetSource = targetSource;
}

public MethodInterceptor getMethodInterceptor() {
return methodInterceptor;
}

public void setMethodInterceptor(MethodInterceptor methodInterceptor) {
this.methodInterceptor = methodInterceptor;
}

public MethodMatcher getMethodMatcher() {
return methodMatcher;
}

public void setMethodMatcher(MethodMatcher methodMatcher) {
this.methodMatcher = methodMatcher;
}
}
Loading

0 comments on commit 9207c6e

Please # to comment.