Shaun's public blog


  • Home

  • Tags

  • Categories

  • Archives

SWT

Posted on 2025-10-04 | In PTE

50-70 词, 步骤

第一步:摘抄

至少分散抄三句话:首句+尾句+中间段落的一句(主要看是否在however/but等转折词后;或者although让步状语的主句;或者in conclusion等总结句)

第二步连接词

我比较常用的是基础的连接词:and/but/because/so,but主要读前后是否存在转折,because和so主要读前后是否存在因果关系。大家如果实在没有思路也可以考虑用which means that,就不需要思考逻辑关系。

paraphrase

paraphase 第(1)步必须要有,(2)(3)(4)可3选2比较稳妥! (1)缩写句子:删掉从句、形容词、状语成分 (2)句式变化:主动变被动 (3)词性变化:动词变名词等 (4)同义替换:同义词 (每个逗号简单改1-2处即可)

==(Sentence 1) and (Sentence 2) , which means that (Sentence 3) , but (Sentence 4) , so (Sentence 5==
==)
==

改写

动词变名词

  • They discovered that -> Their discovery is that

强势动词变弱势动词(或弱势动词变强势动词)

  • They demonstrated that -> They gave a demonstration
  • They discovered that -> They made a discovery of

常用改写

动词

  • play a role -> has a role
  • impact -> have a impact on
  • increase -> improve, enhance, prompt
  • serve -> act
  • provide -> supply

名词

  • worker ->employee

形容词

  • important -> vital part

例子

![[Pasted image 20251001154556.png|Pasted image 20251001154556.png]]

![[Pasted image 20251001154732.png|Pasted image 20251001154732.png]]

Secretpad 源码导读

Posted on 2025-10-04

密码初始化

Based on my analysis of the deploy scripts, here is how the user creation and password handling process works:

  1. User and Password Input:

    • The main script, scripts/deploy/secretpad.sh, is responsible for setting up the environment.
    • Inside this script, the account_settings function prompts the interactive user to enter a username and password.
    • It performs basic validation on the username (check_user_name) and password (check_user_passwd) complexity.
    • If a password is not provided or is invalid after a few tries, a random one is generated by the generate_password function.
  2. Passing Credentials to the Application:

    • The shell scripts do not calculate the password hash.
    • Instead, the plaintext username and password, stored in the SECRETPAD_USER_NAME and SECRETPAD_PASSWORD environment variables, are passed directly into the secretpad Docker container when it’s started. You can see this in the docker run command within the start function of secretpad.sh.
  3. Password Hashing (Inside the Java Application):

    • The password hashing itself happens within the Java application running inside the container. The application reads these environment variables on startup, calculates the hash, and then stores the result in the user_accounts table.

Here is the breakdown of how, when, and where the password hash is calculated:

  • When: The process happens when the Secret-Pad application starts up.

  • Where: The logic is located in the DbDataInit.java file at secretpad-web/src/main/java/org/secretflow/secretpad/web/init/DbDataInit.java.

  • How:

    1. The initUserAndPwd method inside the DbDataInit class is triggered on startup.
    2. It reads the username and password from configuration properties (secretpad.auth.pad_name and secretpad.auth.pad_pwd). ==These properties are populated by the SECRETPAD_USER_NAME and SECRETPAD_PASSWORD environment variables you saw in the shell scripts.==
    3. It then calculates the password hash using the Sha256Utils.hash(password) method.
    4. The resulting SHA-256 hash is stored in the passwordHash field of the AccountsDO entity, which is then saved to the user_accounts table in your database.

    In short, the application uses a SHA-256 hashing algorithm to protect the user’s password.

init script

please tell me when these init function is called. And where is this configuration? @secretpad-web/src/main/java/org/secretflow/secretpad/web/init/

The classes you listed implement either ==CommandLineRunner or ApplicationRunner==. In Spring Boot, any bean that implements these interfaces will have its run() method executed after the application context has been loaded, but before the application starts accepting requests.

  1. @Order annotation: This determines the sequence of execution.
    • @Order(Ordered.HIGHEST_PRECEDENCE): Runs first. DbDataInit has this, so it is executed before the others.
    • @Order(Ordered.LOWEST_PRECEDENCE): Runs last. Most other initializers have this, meaning they run after DbDataInit in an otherwise undetermined order.

CommandLineRunner the method itself runs every time you launch the program.

The run method is executed once every time the application starts.

Here is the sequence of events:

  1. You start the Secretpad application (e.g., by running the JAR file).
  2. Spring Boot initializes and loads all its components.
  3. As part of this startup process, Spring Boot finds the DbDataInit bean and executes its run() method.
  4. The application is now fully running.
  5. You stop the application.

— LATER —

  1. You start the Secretpad application again.

  2. Spring Boot initializes again.

  3. It finds the DbDataInit bean and executes its run() method again.

    So, the method itself runs every time you launch the program.

改密码的逻辑

You are correct. The run method in DbDataInit is executed every time the application starts, but the account is only created once.

This is due to two main reasons:

  1. CommandLineRunner Lifecycle: As a CommandLineRunner, Spring Boot guarantees that the run method is executed only one time during the application’s startup sequence. ==It doesn’t run again unless the application is restarted.==

  2. Defensive Code Logic: The initUserAndPwd method is written defensively to prevent creating duplicate users. Let’s look at the key lines:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
        // 1. Try to find a user with the configured name in the database.  
    Optional<AccountsDO> accountsDOOptional = userAccountsRepository.findByName(accountsDO.getName());
    // 2. Check if the user was found. if (accountsDOOptional.isEmpty()) {
    // 3. If the user does NOT exist, save the new account. This only happens on the very first run. userAccountsRepository.save(accountsDO);
    } else { // 4. If the user ALREADY exists, just log a message and update the password. log.info("user {} already exists update password", username);
    accountsDOOptional.get().setPasswordHash(Sha256Utils.hash(password));
    userAccountsRepository.save(accountsDOOptional.get());
    } ```
    In summary:

    * **On the first application startup**: The database is empty, `findByName` returns nothing, the `if` block is executed, and the account is created.
    * **On every subsequent startup**: `findByName` finds the account created previously, the `else` block is executed, and the existing account's password is simply updated. No new account is created.

    This pattern makes the initialization process **idempotent**—meaning it can run multiple times without changing the result beyond the initial execution.

    ---


    # 第一个api,api/v1alpha1/p2p/project/list

    When you call the `api/v1alpha1/p2p/project/list` API, the following functions are called in order:

    1. `org.secretflow.secretpad.web.controller.p2p.P2PProjectController.listP2PProject(...)`
    2. `org.secretflow.secretpad.service.impl.ProjectServiceImpl.listP2PProject(...)`

    This API call **does not modify any tables** in the database. It is a read-only operation that retrieves project information from the following tables:

    * `project_inst`
    * `project_approval_config`
    * `project`
    * `vote_request`
    * `project_node`
    * `project_graph`
    * `project_job`
    * `inst`


    ## ApiResource 注解

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

    /**

    • api code * * @return api resource code {@link org.secretflow.secretpad.common.constant.resource.ApiResourceCodeConstants}
    • / String code();
      }


*   `@Target(ElementType.METHOD)`: This means the annotation can only be applied to methods.  
*   `@Retention(RetentionPolicy.RUNTIME)`: This means the annotation is available at runtime, which allows for frameworks or custom logic to inspect it.  
*   `String code();`: This defines a single attribute named `code` that takes a `String` value. **==这里的code 不是函数,见[[Java 中的注解 annotation|Java 中的注解 annotation]]==**

In the `P2PProjectController`, you can see it applied to the API methods:  
  
```java  
@ResponseBody  
@PostMapping(value = "/list", consumes = "application/json")  
@Operation(summary = "list project", description = "list project")  
@ApiResource(code = ApiResourceCodeConstants.PRJ_LIST)  
public SecretPadResponse<List<ProjectVO>> listP2PProject() {  
    return SecretPadResponse.success(projectService.listP2PProject());}  

In this example, @ApiResource(code = ApiResourceCodeConstants.PRJ_LIST) associates the listP2PProject method with the resource code PRJ_LIST.

The values for the code attribute are defined as constants in the ApiResourceCodeConstants class. For example, PRJ_LIST is defined as:

public static final String PRJ_LIST = "PRJ_LIST";```  
  
By using this annotation, the application can implement cross-cutting concerns like checking if a user has the necessary permissions to access a specific API endpoint based on the resource code.

##  注解 与授权的关系

The `@ApiResource` annotation, in conjunction with `PRJ_LIST`, is directly related to permission control in the application. Here's how it works:  
  
**1. Annotation and Resource Code:**  
  
As we've seen, the `@ApiResource` annotation is used to mark API endpoint methods. It takes a `code` as a parameter, which is a `String` that uniquely identifies that API resource. In the case of the project list API, the code is `PRJ_LIST`.  
  
```java  
@ApiResource(code = ApiResourceCodeConstants.PRJ_LIST)  
public SecretPadResponse<List<ProjectVO>> listP2PProject() {  
    // ...}  

2. AOP-based Interception:

The application uses Aspect-Oriented Programming (AOP) to intercept calls to methods annotated with @ApiResource. This is done in the InterfaceResourceAspect class.

This aspect defines a “pointcut” that targets any method annotated with @ApiResource. When such a method is called, the check method in the aspect is executed before the actual API method.

3. Permission Checking Logic:

The check method in InterfaceResourceAspect extracts the code from the @ApiResource annotation (e.g., PRJ_LIST) and calls the apiResourceAuth.check(apiResource.code()) method.

The DefaultApiResourceAuth class implements the ApiResourceAuth interface and contains the core permission checking logic. It does the following:

  • It retrieves the current user’s information from the UserContext.

  • It checks if the user has the ALL_INTERFACE_RESOURCE permission. If so, the check passes.

  • If not, it checks if the user’s apiResources (a set of resource codes they are allowed to access) contains the code from the annotation (e.g., PRJ_LIST).

  • *4. UserContext and Permissions:**

    The UserContext holds the currently logged-in user’s details, including a set of strings representing the API resources they are permitted to access. When a user logs in, their permissions are fetched and stored in the UserContext.

    In summary, the workflow is as follows:

  1. A user makes a request to an API endpoint (e.g., /api/v1alpha1/p2p/project/list).
  2. The InterfaceResourceAspect intercepts the call to the controller method because it’s annotated with @ApiResource.
  3. The aspect extracts the resource code (PRJ_LIST) from the annotation.
  4. It calls the ApiResourceAuth service to check if the current user has permission for that resource code.
  5. The DefaultApiResourceAuth service checks the user’s permissions stored in the UserContext.
  6. If the user has the PRJ_LIST permission (or the ALL_INTERFACE_RESOURCE permission), the check passes, and the controller method is executed.
  7. If the user does not have the required permission, an exception is thrown, and the user is denied access.

注解的详细讲解

Of course. Let’s break down what’s happening. It’s a great question because the magic isn’t in the @ApiResource annotation itself, but in how the application uses it.

1. @interface is not a regular interface

First, a key clarification: In Java, @interface is used to declare an annotation, not a standard interface that a class would implement.

  • An interface defines a contract (a set of methods) that a class must implement.

  • An @interface defines a new type of annotation. The annotation itself is just metadata; it’s a marker that can be placed on code, but it doesn’t contain any logic on its own.

    So, you won’t find a class that says class MyClass implements ApiResource. That’s not how annotations work.

    2. How it’s Used: Aspect-Oriented Programming (AOP)

    The “implementation” you’re looking for is not in a class that implements @ApiResource, but in a class that reads the annotation and acts on it. This is done using a powerful programming paradigm called Aspect-Oriented Programming (AOP).

    In this project, the class InterfaceResourceAspect.java is an “aspect”. Think of it as a special module that can intercept and add behavior to existing code without modifying that code directly.

    Here is the relevant code from InterfaceResourceAspect.java:

    @Aspect  
    @Component  
    public class InterfaceResourceAspect {    // ...    @Autowired  
      private ApiResourceAuth apiResourceAuth;  
    
      @Pointcut("@annotation(org.secretflow.secretpad.common.annotation.resource.ApiResource)")  
      public void pointCut() {  
      }  
      @Around("pointCut() && args(data) && @annotation(apiResource)")  
      public Object check(ProceedingJoinPoint joinPoint, Object data, ApiResource apiResource) throws Throwable {        // ...        if (!apiResourceAuth.check(apiResource.code())) {  
              throw SecretpadException.of(AuthErrorCode.AUTH_FAILED, apiResource.code());  
          }        return joinPoint.proceed();  
      }    // ...}  
    

    3. The Permission Control Workflow

    Here is the step-by-step process that connects the annotation to the permission check:

  1. A Request Arrives: A user calls the /api/v1alpha1/p2p/project/list endpoint.

  2. AOP Interception: The Spring Framework, which powers the application, sees that the listP2PProject method is annotated with @ApiResource. Because of the @Aspect and @Pointcut configuration in InterfaceResourceAspect, it intercepts the call before the listP2PProject method’s code is executed.

  3. The check Method Runs: The @Around advice in the aspect is triggered, and its check method is executed.

  4. Metadata is Read: The check method receives the ApiResource annotation instance as a parameter. It then calls apiResource.code() to get the string value you provided (in this case, PRJ_LIST).

  5. Permission Check is Delegated: The aspect then calls apiResourceAuth.check("PRJ_LIST"). Here, apiResourceAuth is an instance of a class that implements the ApiResourceAuth interface. The actual implementation is DefaultApiResourceAuth.

  6. The Real Check Happens: The DefaultApiResourceAuth class performs the logic:

    • It gets the current user’s data from the UserContext.
    • It checks if the user’s list of permissions (stored in UserContext.apiResources) contains the string "PRJ_LIST".
  7. Execution Proceeds or Fails:

    • If the check method returns true, the aspect calls joinPoint.proceed(), which allows the original listP2PProject method to finally execute.
    • If the check method returns false, the aspect throws an AuthErrorCode.AUTH_FAILED exception, and the request is denied with a permission error. The controller method is never executed.

    So, the @ApiResource annotation is not an interface to be implemented. It is a marker whose data is read by an AOP aspect, which then triggers the actual permission-checking logic.


PTE WE

Posted on 2025-10-04 | In PTE

Template

It is undeniable that [1] plays a vital role in our society. Therefore, the debate over whether [2] has attracted considerable attention from the public. As far as I am concerned, I firmly advocated that [3].

First and foremost, there are numerous reasons why I believe that [4], but the most compelling reason is that [5]. Nobody can deny the fact that [6] brings significant benefits. According to the latest research conducted by the United States [7]. As a result, it is evident that [8].

Moreover, it should be emphasized that [9]. Based on my own experience, by engaging in [10], I have been able to [11]. Furthermore, an increasing number of people hold the view that [12]. However, I strongly maintain that [13] has a more beneficial impact on [14]. I still remember one of my best friends repeatedly telling me that [15] is of great importance.

In conclusion, we should never overlook what has been discussed above. Nowadays, more and more people are paying attention to [15]. It can not only [16] but also [17]. Therefore, I firmly believe that [18].

Untitled

Posted on 2025-10-04 | In 测试

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

DI RL模版

Posted on 2025-10-04 | In PTE

DI

其余

  • 缓冲句
    • Speaking to A
  • 标题
    • The title is
  • 颜色
    • Red represents A
    • ==A is shown in red==
  • 转变 convert
    • A convert to B
    • A flow to B
  • 分类
    • The data is divided into 2 categories, such as A and B
  • 形状
    • This shape is circle
    • 流程图

  • This graph gives information about xxxx
  • The items includes xxx
    • According to the graph, the first step is xxx
    • Moving on, the second step is xxx
    • In addition, the third step is xxx
    • To finish, the last step is xxx
  • In conclusion, this graph provides information about xxx

数字类的

  • This pie/bar/line chart gives information about xxx
  • 最大最小值
    • If you look at A(或者the graph), the largest number can be found in xxx, which about 数字
    • If you look at A(或者the graph), the minimum number is 数字, which is related to xxx
    • The smallest number is xxx, which is related to xxx
  • 数字+比较
    • Looking at the graph, I notice that the number of xxx is xxx, which is greater than xxx
  • 趋势
    • In summary, we can see that this graph is going up/down

地图类的

不要逻辑

  • This picture gives information about , which includes xxx, xxx and xxx
  • 位置
    • When you looking at the upper left of the corner, I notice some green colors, which is related to xxx
    • In the upper left area, there is a xxxx
    • On the top part of the image
    • On the bottom of the graph,
    • Besides, we can see xxx and xxx in the right corner.
    • In the middle of the picture, I notice xxx
  • 如果是地图
    • East
    • West
    • North
    • South

RL

每一句话一定用不同的句式

  • This lecture mainly talks about xxx
  • Firstly, the speaker mentioned about A ==at the beginning.==
  • Secondly, the speaker mentioned B, ==which is highly related== to C
  • In addition, the speaker ==also provides details about== D and E.
  • Also, from the speaker ==we can get a lot of information about== F
  • In conclusion, this lecture covers the topic about xxx

DI 模版

Posted on 2025-10-04 | In PTE

流程图

  • This graph gives information about xxxx
  • The items includes xxx
    • According to the graph, the first step is xxx
    • Moving on, the second step is xxx
    • In addition, the third step is xxx
    • To finish, the last step is xxx
  • In conclusion, this graph provides information about xxx

数字类的

  • This pie/bar chart gives information about xxx
  • 最大最小值
    • If you look at A(或者the graph), the largest number can be found in xxx, which about 数字
    • If you look at A(或者the graph), the minimum number is 数字, which is related to xxx
    • The smallest number is xxx, which is related to xxx
  • 数字+比较
    • Looking at the graph, I notice that the number of xxx is xxx, which is greater than xxx
  • 趋势
    • In summary, we can see that this graph is going up/down

地图类的

不要逻辑

  • This picture gives information about , which includes xxx, xxx and xxx
  • 位置
    • When you looking at the upper left of the corner, we can see some green colors, which is related to xxx
    • In the upper left area, there is a xxxx
    • Besides, we can see xxx and xxx in the right corner.
    • In the middle of the picture, I notice xxx

其余

  • 颜色
    • There is a green mark with
  • 转变 convert
    • A convert to B

Java 中的注解 annotation

Posted on 2025-10-04

注解的定义

也可以见 [[Secretpad 源码导读#注解的详细讲解|Secretpad 源码导读 > 注解的详细讲解]]

In the definition of @ApiResource, String code(); looks like a function declaration, but in the context of an annotation, it defines an attribute named code that accepts a String value. This is the standard syntax for declaring attributes within a Java annotation.

When you use the annotation, as in @ApiResource(code = ApiResourceCodeConstants.PRJ_LIST), you are not calling a function. Instead, you are assigning a value (ApiResourceCodeConstants.PRJ_LIST) to the code attribute of the @ApiResource annotation.

So, to clarify:

  • In the annotation definition (@interface): String code(); declares an attribute named code.

  • In the annotation usage (@ApiResource(...)): code = "..." assigns a value to that code attribute.

    It’s a syntactic quirk of Java annotations that the attribute declaration looks like a method signature.
    .

APO 与Spring boot 配置

Since the @secretpad-web/src/main/java/org/secretflow/secretpad/web/aop/InterfaceResourceAspect.java is an aspect. How does the aspect is configured in this spring-boot project? How does this aspect work? How does it know which thing should intercept? All of the requests or all of methods should intercept?

Excellent questions. You’re digging into the core of how Spring Boot and AOP work together, which is often described as “magic” but is actually a very well-defined process.

Let’s break it down.

1. How is the Aspect Configured? (The “Auto-Magic”)

In a modern Spring Boot project, you don’t need extensive XML configuration for AOP. The configuration is primarily done through annotations and auto-configuration.

  • Dependency: The project includes the spring-boot-starter-aop dependency (usually as a transitive dependency from starters like spring-boot-starter-web). This starter tells Spring Boot to enable AOP support.

  • @Aspect and @Component: The InterfaceResourceAspect class is annotated with both @Aspect and @Component.

    • @Aspect tells the Spring AOP framework that this class contains “advice” and “pointcuts” that should be woven into the application.
    • @Component makes the aspect itself a Spring bean, so it’s managed by the Spring container and can have other dependencies (like ApiResourceAuth) injected into it.

    That’s it for configuration. When the application starts, Spring scans for components, finds the InterfaceResourceAspect, recognizes it as an aspect, and automatically creates the necessary proxies to make it work.

    2. How Does It Work? (The Proxy Pattern)

    The “magic” behind AOP is a design pattern called the Proxy Pattern.

  1. When the application starts, Spring identifies all the beans that need to be intercepted by an aspect (in this case, any bean with a method annotated with @ApiResource).

  2. Instead of creating and injecting the original bean (e.g., your P2PProjectController), Spring creates a Proxy object that wraps your original controller.

  3. This proxy has the exact same methods as your controller, but it has the aspect’s logic (the “advice”) woven into it.

  4. When another part of your application calls a method on your controller, it’s actually calling the method on the proxy.

  5. The proxy then executes the aspect’s advice (the check method). Inside the advice, the aspect decides whether to call the original method on the real controller object (joinPoint.proceed()) or to block it (by throwing an exception).

    3. How Does It Know What to Intercept? (@Pointcut)

    This is the most crucial part of your question. The aspect does not intercept all requests or all methods. It’s very specific, and this is defined by the @Pointcut annotation.

    Look at this line in InterfaceResourceAspect.java:

    @Pointcut("@annotation(org.secretflow.secretpad.common.annotation.resource.ApiResource)")  
    

    This is a pointcut expression. It tells the AOP framework exactly where to apply the advice. Let’s break it down:

  • @annotation(...): This tells the aspect to target (or “cut” into) any method that is annotated with a specific annotation.

  • org.secretflow.secretpad.common.annotation.resource.ApiResource: This is the fully qualified name of the annotation.

    So, this pointcut expression means: “Intercept any method, in any Spring bean, that has the @ApiResource annotation.”

    4. The Advice Itself (@Around)

    The @Around annotation defines the code that runs when the pointcut is matched.

    @Around("pointCut() && args(data) && @annotation(apiResource)")  
    public Object check(ProceedingJoinPoint joinPoint, Object data, ApiResource apiResource) throws Throwable {    // ... permission checking logic ...    return joinPoint.proceed();  
    }  
    
  • @Around: This is a type of advice that “wraps” the original method call. It gives the aspect full control to run code before and after the method, and even to prevent the method from running at all.

  • pointCut(): This links the advice to the @Pointcut we defined above.

  • @annotation(apiResource): This is a clever trick. It not only helps match the pointcut but also captures the actual annotation instance from the method and makes it available as a parameter (apiResource) to the check method. This is how the aspect gets the code value by calling apiResource.code().

  • joinPoint.proceed(): This is the line that executes the original, intercepted method (e.g., listP2PProject). If this line is never called, the controller method never runs.


apo 中的pointcut

Of course. You’re asking the central question of AOP: “How do I specify where my aspect’s logic should run?” The answer is the pointcut.

The Concept of a Pointcut

Think of a Pointcut as a query or a predicate that selects a set of “join points”.

  • A Join Point is a well-defined point in the execution of a program. In Spring AOP, a join point is always the execution of a method.

  • A Pointcut is the expression that matches a collection of these join points. It’s the “WHERE” clause of AOP.

    So, if your entire application’s execution flow is a huge collection of method calls, a pointcut is a rule you write to select a specific subset of those method calls to which you want to apply your advice (your aspect’s logic).

    Pointcut Designators: Beyond @annotation

    Besides @annotation, Spring AOP provides a powerful set of “pointcut designators” (PCDs) to select join points. Here are the most common ones:

    1. execution() - The Workhorse

    This is the most common and powerful designator. It matches method execution join points based on a detailed signature pattern.

  • *Syntax:** execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

  • ? indicates an optional part.

  • * is a wildcard for any single element.

  • .. is a wildcard for zero or more elements.

  • *Examples:**

  • Match any public method:

    @Pointcut("execution(public * *(..))")  
    ```*   Match any method in the `ProjectService`:  
    ```java  
    @Pointcut("execution(* org.secretflow.secretpad.service.ProjectService.*(..))")  
    ```*   Match any method in any class within the `web.controller` package:  
    ```java  
    @Pointcut("execution(* org.secretflow.secretpad.web.controller..*.*(..))")  
    ```    (Note the `..` after `controller` to match sub-packages).  
    
    #### 2. `within()` - Type-Based Matching  
    
    This selects all join points (method executions) within classes that match a certain type pattern. It's simpler than `execution` if you just want to target a whole class or package.  
    
  • *Examples:**

  • Match all methods in the P2PProjectController class:

    @Pointcut("within(org.secretflow.secretpad.web.controller.p2p.P2PProjectController)")  
    ```*   Match all methods in any class in the `service` package (and its sub-packages):  
    ```java  
    @Pointcut("within(org.secretflow.secretpad.service..*)")  
    

    3. args() - Argument-Based Matching

    This matches method executions where the arguments at runtime are instances of the given types.

  • *Examples:**

  • Match any method that takes a single String as its first parameter:

    @Pointcut("args(String, ..)")  
    ```*   Match any method that takes exactly one argument of type `CreateProjectRequest`:  
    ```java  
    @Pointcut("args(org.secretflow.secretpad.service.model.project.CreateProjectRequest)")  
    

    4. @within() - Annotation on Type

    This is similar to within(), but it matches any join point within a type that has a given annotation.

  • *Example:**

  • Match all methods in any class that is annotated with @RestController:

    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")  
    

    5. @target() - Annotation on Target Object’s Class

    This is slightly different from @within. It checks if the class of the target object being invoked has the given annotation. In most simple cases, it behaves like @within, but it can differ in complex proxying scenarios.

  • *Example:**

  • Match method executions where the target object’s class is annotated with @Service:

    @Pointcut("@target(org.springframework.stereotype.Service)")  
    

    6. bean() - Spring Bean Name

    This allows you to target a specific Spring bean by its name (its ID in the Spring container).

  • *Example:**

  • Match all methods on the Spring bean named projectServiceImpl:

    @Pointcut("bean(projectServiceImpl)")  
    

    Combining Pointcuts

    You can also combine these expressions using logical operators (&&, ||, !) to create very precise and powerful pointcuts.

    For example, you could intercept all public methods within the service layer that return a String:

    @Pointcut("execution(public String org.secretflow.secretpad.service..*.*(..))")  
    

    The InterfaceResourceAspect you saw uses this combination implicitly in the @Around advice: pointCut() && args(data) && @annotation(apiResource). This means “apply this advice where the pointCut() matches, AND where the method has arguments that can be bound to data, AND where the method has an annotation that can be bound to apiResource.”

7 posts
2 categories
9 tags
© 2025 Shaun Ko
Powered by Hexo
|
Theme — NexT.Muse v5.1.4