spring-aop-1

What 1.Spring of aop that?

Comparison with OOP, the AOP is a process cross-cutting of some problems, these problems do not affect the cross-cutting of the main logic implementation, it will be scattered to various parts of the code, it is difficult to maintain. AOP is to separate these issues and the main business logic, business logic with the main purpose of decoupling.

2.aop application scenarios

Logging

ASD

Efficiency check

Transaction Management

3. Some of the concepts about aop

join point

  -> connection point: The method of the target object

  -> For example: dao four layer method to add the transaction, the four methods that become connection points.

Pointcut

  -> tangent point: connection point set,

  Cut-off point there are two key elements:

  1.where: Where enhancement method?

  2.when: When enhanced

  The cut points can be understood as a table in the database, then the connection point is a data table.

Weaving

  -> weaving: the proxy logic is added to the process on the target object is called weaving

advice

  -> Notifications

  It consists of two parts:

  1. notification specific content (proxy logic code)

  2.where: Where notification -> Agent logic code woven into that position audiences

Aspect

  -> section

  It is in a class AspectJ

  In xml it is a label  

target 

  -> the target object, the original object

aop Proxy

  -> proxy object that contains the object code of the code and add the original object

AspectJ and the relationship 4.springAop

Relationship (1) aop with the springAop

aop is an idea, springAop achieve aop thought. ioc similar relationship with the di

(2) spring AOP provides two programming styles

  @AspectJ support ------------> use aspectj comments

  Schema-based AOP support -----------> xml aop: config namespace

  Proof: spring, through source code analysis, we can know that spring bottom using JDK or CGLIB to complete the proxy and gives aspectj documents, and springAOP spring is different from the official website

(3) a brief summary

  spring supports syntax of AspectJ, but the specific underlying implementation is to achieve its own spring.

  JavaScript learn java syntax similar to the same.

5.springAop based AspectJ implementation

(1)

① use Java configuration enables @AspectJ support --- require catches aspectj appropriate pom file

@Configuration
@ComponentScan("cn.cg.*")
//启动@AspectJ支持 @EnableAspectJAutoProxy
public class AppConfig { }

 

② use xml configuration enables @AspectJ support

<aop:aspectj-autoproxy/>

(2) declare a Target

@Component
public class IndexDao {
    public void query(){
        System.out.println("query");
    }
}

(3) a declaration aspect

@Component
@Aspect
public class DaoAspect {

}

(4) Sound point Mingqie

@Component 
@Aspect 
public  class DaoAspect { 
  // tangent point 
    @Pointcut ( "Execution (cn.cg.target.IndexDao.query * (..))" )
     public  void PointCut () { 
        // empty, if the execution code does not write 
    } 
    
}

(5) declare a notification @Component the @Aspect

public  class DaoAspect { 

    @Pointcut ( "Execution (cn.cg.target.IndexDao.query * (..))" )
     public  void PointCut () {} 
    // Keywords: 
  // When -> before -> front set notification -> specific logic code is woven into the front of the target method
@Before (
"PointCut ()" ) public void before () { // specific logic code System.out.println ( "before" ); } }

(6) Test

  

public class MainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        IndexDao dao = (IndexDao) ac.getBean("indexDao");
        dao.query();
    }
}

console:

before
query

success!!!

(7) Supported Pointcut Designators -> spring support entry point indicator

A total of nine kinds: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop-pointcuts

Introduce three of them -> general development of the most commonly used

①execution

For matching method execution join points ---> A method for performing matching connection point

For example: * public cn.cg.target.IndexDao.query (..)
Since the cut-off point is connected to a collection point, so support *, &&, || and other symbols 
such as: * CN target.Index * * * (..)...
- the Execute given official expression syntax:
Execution (modifiers-pattern?-RET-pattern of the type Declaring-of the type-pattern? name-pattern (pattern-param) 
            throws-pattern?) 
where the question mark indicates that the current entry may or may not, in which the semantics of the following 
modifiers-pattern : visibility, such as public, protected process; 
RET-pattern-type: the type of the return value, such as int, void, etc.; 
Declaring-pattern-type: the method where the full path name of the class, such as com.spring.Aspect; 
name-pattern: the type of method names, such as buisinessService (); 
param-pattern: a method of parameter types, such as java.lang.String; 
throws-pattern: the type of exception thrown methods, such as java.lang.Exception;

②within

 Limits matching to join points within certain types -> limit matches the connection point of a specific type

The minimum particle size is based expression
  
@Pointcut ( "within (com.cg.dao. * )") // packet matches any of the methods com.chenss.dao 
@Pointcut ( "within (com.cg.dao .. * )") // match com the method of any .chenss.dao package and its sub-packet

Case:

Configuring a new Dao

//添加新的Dao
@Component
public class UserDao { public void Personquery(){ System.out.println("query"); } }

Configuration cut-off point

Methods //cn.cg.target.UserDao at all 
// if the expression is changed to: @Pointcut ( ". within (cn.cg.target.UserDao *)") will not take effect
@Pointcut("within(cn.cg.target.UserDao)")
    public void pointCut2(){

    }

    @Before("pointCut2()")
    public void before( ){
        //具体的逻辑代码
        System.out.println("before");
    }

test:

public class MainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        IndexDao dao = (IndexDao) ac.getBean("indexDao");
        dao.query();
        System.out.println("--------------------------");
        UserDao dao2 = (UserDao) ac.getBean("userDao");
        dao2.Personquery();
    }
}

console:

query
--------------------------
before
query

in conclusion:

The minimum particle size is based expression

 

③agr 

args effect expression match specified parameter specifies the type and number of parameters of the method, regardless of the package and class names 


/ ** 
 * args difference is that with the execution: 
 * args parameter type matching is passed to the method runtime 
 * execution (* * (java.io.Serializable)) matching method is a method of the type specified in the parameter declaration. 
 * / 
@Pointcut ( "args (the java.io.Serializable)") // Parameter Type passed runtime matching the specified type, and the number of parameters and sequence matching 
@Pointcut ( "@ args (com.chenss.anno. Chenss) ") // run-time type accepts a parameter, and a parameter having passed @Classified

Case:

  Modify indexDao

@Component
public class IndexDao {
    public void query(){
        System.out.println("query");
    }
    public void query(String str){
        System.out.println("query"+str);
    }
}

Cut-off point:

  

 @Pointcut("args(java.lang.String)")
    public void pointCut3(){

    }
    @Before("pointCut3()")
    public void before( ){
        //具体的逻辑代码
        System.out.println("before");
    }

test:

public class MainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        IndexDao dao = (IndexDao) ac.getBean("indexDao");
        dao.query();
        System.out.println("--------------------------");
        UserDao dao2 = (UserDao) ac.getBean("userDao");
        dao2.Personquery();
        System.out.println("--------------------------");
        dao.query("1111");
    }
}

console:

query
--------------------------
query
--------------------------
before
query1111

in conclusion: 

Args effect expression match specified parameter specifies the type and number of parameters methods, regardless of the package and class names

(4) ||, && ,! use

Case ---> Presentation &&

UserDao for modification do control

@Component
public class UserDao {
    public void Personquery(){
        System.out.println("query");
    }
    public void Personquery(String str){
        System.out.println("query"+str);
    }
    
}

Add cut-off point

// indexDao class for an incoming type String method parameter, and the parameter is present and only a 
@Pointcut ( "WITHIN (cn.cg.target.IndexDao) && args (java.lang.String)" ) public void pointCut4 ( ) { } @Before ( "pointCut4 ()" ) public void before () { // specific logic code System.out.println ( "before" ); }

test:

public class MainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        IndexDao dao = (IndexDao) ac.getBean("indexDao");
        dao.query("index");
        System.out.println("--------------------------");
        UserDao dao2 = (UserDao) ac.getBean("userDao");
        dao2.Personquery("person");
        System.out.println("--------------------------");
        dao.query();
        System.out.println("--------------------------");
        dao2.Personquery();
    }
}

 

console:

  

before
queryindex
--------------------------
queryperson
--------------------------
query
--------------------------
query

in conclusion:

  IndexDao only enhances the query (String str) method

(5) target ---- point interfaces and subclasses

 ---- the this time JDK proxy, and the proxy class interfaces Proxy point, point interfaces and when subclasses cglib agent (without using proxy)

 

 

/ ** 
 * It should be noted here that, if the configuration settings proxyTargetClass = false, or the default is false, it is a JDK proxy, otherwise use a proxy CGLIB * JDK proxy implementation is based on the interface, the proxy class inherits Proxy , implement the interface. 
 * The CGLIB inherit the proxy class to implement.    Subsequent essays will be mentioned 
 * so use target will ensure that target unchanged, association objects are not affected by this setting. 
 * However, when using this object, according to the settings of the option to determine whether the object is found. 


* / @Pointcut ( "target (com.chenss.dao.IndexDaoImpl)") // target object, which is the object being proxied. Limit the target object is com.chenss.dao.IndexDaoImpl class @Pointcut ( "the this (com.chenss.dao.IndexDaoImpl)") // current object, which is the proxy object, the proxy object when acquiring new target object through a proxy way objects, and the original value is not a @Pointcut ( "@ target (com.chenss.anno.Chenss)") // any method of the target object has @Chenss in @Pointcut ( "@ within (com.chenss.anno.Chenss ) ") // equivalent to @targ

 Case:

  Add cut-off point

@Pointcut("this(cn.cg.target.IndexDao)")
    public void pointCut5(){

    }

    @Before("pointCut5()")
    public void before( ){
        //具体的逻辑代码
        System.out.println("before");
    }

 

  Creating interfaces

public interface Dao {
    public void query();
    public void query(String str);
}

  IndexDao implement the interface

@Component
public class IndexDao implements Dao {
    public void query(){
        System.out.println("query");
    }
    public void query(String str){
        System.out.println("query"+str);
    }
}

  test:

public class MainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        IndexDao dao = (IndexDao) ac.getBean("indexDao");

    }
}

  console:

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy18 cannot be cast to cn.cg.target.IndexDao
    at cn.cg.MainClass.main(MainClass.java:18)

why?

Already mentioned above because IndexDao realized Dao interfaces ---> object so as to obtain from the container -> proxy object, he extends Proxy implements Dao

So modify the test method

public class MainClass {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        Dao dao = (Dao) ac.getBean("indexDao");
        dao.query();
    }
}

  console:

query

 

Why not target method to enhance it?

Consistent with the cause of the problems described above, because the container is not obtained proxy object implementation class IndexDao

Solution: Use proxy cglib

@Configuration
@ComponentScan("cn.cg.*")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig { }

console:

before
query

The reason: Because cglib agent is achieved through inheritance IndexDao

 

 

 

  

Guess you like

Origin www.cnblogs.com/cg961107/p/11247931.html
Recommended