From: www.jianshu.com/p/ebaefa1b0…

The concepts in AOP have been explained in previous articles, but they are implemented by code, each time using a ProxyFactory to create a proxy. Next, we’ll look at the automatic proxy approach to AOP in Spring, based on Schema configuration files and @AspectJ annotations. Of course, automatic proxy implementation mechanism, in the following chapter analysis, this right when review, but also for the following source code analysis to pave the way.

1. Ordinary section
  • The target object

package com.lyc.cn.v2.day06;

public interface Animal {
    void sayHello(String name,int age);

    void sayException(String name, int age);
}
Copy the code

package com.lyc.cn.v2.day06;

public class Cat implements Animal {

    @Override
    public void sayHello(String name, int age) {
        System.out.println("-- Call enhanced method");
    }

    @Override
    public void sayException(String name, int age) {
        System.out.println("== throw an exception:"+ 1/0); }}Copy the code

  • Cut class

package com.lyc.cn.v2.day06; import org.aspectj.lang.ProceedingJoinPoint; Public class CatAspect {/** ** 前 提 示 */ public void beforeAdvice(String name, int age) {system.out.println () public void beforeAdvice(String name, int age) {system.out.println ("== pre-enhanced, name:" + name + ", age:"+ age); Public void afterExceptionAdvice(String name, int age) {system.out.println ("== after exception enhancement, name:" + name + ", age:"+ age); } public void afterReturningAdvice(String name, int age) {system.out.println ("== post-return enhancement, name:" + name + ", age:"+ age); } public void afterAdvice(String name, int age) {system.out.println ("== final enhancement after, name:" + name + ", age:"+ age); } /** * public Object roundAdvice(ProceedingJoinPoint p, String name, int age) {system.out.println ("== wrap enhancement begins, name:" + name + ", age:" + age);
        Object o = null;
        try {
            o = p.proceed();
            Object[] args = p.getArgs();
            if(null ! = args) {for (int i = 0; i < args.length; i++) {
                    System.out.println("== Surround enhancement parameter value:" + args[i]);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("== Wrap enhancement end, name:" + name + ", age:" + age);
        returno; }}Copy the code

  • The configuration file

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <! -- Target object --> <bean id="cat" class="com.lyc.cn.v2.day06.Cat"/ > <! -- Section class --> <bean id="catAspect" class="com.lyc.cn.v2.day06.CatAspect"/ > <! < AOP :config proxy-target-class="true"> <! Pointcut --> < AOP :pointcut id="pointcut" expression="execution(* com.lyc.cn.v2.day06.. *. * (..) ) and args(name,age)"/>
        <aop:aspect ref="catAspect" order="0"> <! Aop :before method= --> < AOP :before method="beforeAdvice" pointcut-ref="pointcut" arg-names="name,age"/ > <! Aop :after-throwing method= aop:after-throwing method= aop:after-throwing method="afterExceptionAdvice" pointcut-ref="pointcut" arg-names="name,age"/ > <! Aop :after-returning enhanced, executed when pointcut selected methods return normally --> < AOP :after-returning method="afterReturningAdvice" pointcut-ref="pointcut" arg-names="name,age"/ > <! Aop :after method= aop:after method="afterAdvice" pointcut-ref="pointcut" arg-names="name,age"/ > <! Aop :around method=? Aop :around method=? Aop :around method="roundAdvice" pointcut-ref="pointcut" arg-names="p,name,age"/>
        </aop:aspect>
    </aop:config>
</beans>
Copy the code

  • Test classes and results

package com.lyc.cn.v2.day06;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

    @Test
    public void test1() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("v2/day06.xml");
        Cat cat = ctx.getBean("cat", Cat.class);
        cat.sayHello("Mei-mei", 3);
    }


    @Test
    public void test2() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("v2/day06.xml");
        Cat cat = ctx.getBean("cat", Cat.class);
        cat.sayException("Mei-mei", 3); }}Copy the code

// Test 1 == pre enhancement, name: Meimei, age: 3 == Surround enhancement begins, name: Meimei, age: 3 -- call enhanced method == Surround enhancement value: Meimei == Surround enhancement value: 3 == End of surround enhancement, name: Meimei, age: 3 == final enhancement, name: Meimei, age: 3 == return enhancement, name: Meimei, age: 3Copy the code

// Test 2 == pre enhancement, name: Meimei, age: 3 == Surround enhancement begins, name: Meimei, age: 3 == Surround enhancement ends, name: Meimei, age: 3 == post final enhancement, name: Meimei, age: 3 == Post return enhancement, name: Meimei, age: 3 == Post return enhancement, name: Meimei, age: 3 == Post return enhancement, name: Meimei, age: 3 == Post return enhancement, name: Meimei, age: 3 == Post return enhancement, name: Meimei, age: 3 == Post return enhancement, name: Meimei, age: 3 == 3java.lang.ArithmeticException: / by zero at com.lyc.cn.v2.day06.Cat.sayException(Cat.java:12) at com.lyc.cn.v2.day06.Cat$$FastClassBySpringCGLIB$$336350b6.invoke(<generated>
Copy the code

I believe that you are familiar with this configuration, and it has been well explained in the configuration file, and the configuration mode of Schema is not so popular, so we will not introduce too much.

2. Introduction enhancement

Spring introduction allows the introduction of new interfaces for target class objects.

  • Introduce interfaces and implementations

package com.lyc.cn.v2.day06; /** * introduce * @author: LiYanChao * @create: 2018-10-28 15:48 */ public interface IIntroduce {void sayIntroduce(); }Copy the code

package com.lyc.cn.v2.day06;

/**
 * @author: LiYanChao
 * @create: 2018-10-28 15:48
 */
public class IntroduceImpl implements IIntroduce {
    @Override
    public void sayIntroduce() {
        System.out.println("-"); }}Copy the code

  • Modify configuration file configuration introduction enhancement

    <aop:aspect/>Add the following configuration to the tag:

<! Types-matching: An AspectJ syntactic type expression that matches the target object to which the interface needs to be imported. 2. Implement-interface: defines the interface to be imported. Default-impl and delegate-ref: Define the default implementation of the imported interface. Choose between default-impl and delegate-ref. Default-impl is the fully qualified name of the default implementation class of the interface and delegate-ref is the delegate Bean name of the default implementation. --> <aop:declare-parents types-matching="com.lyc.cn.v2.day06.Cat"
                 implement-interface="com.lyc.cn.v2.day06.IIntroduce"
                 default-impl="com.lyc.cn.v2.day06.IntroduceImpl"/>
Copy the code

  • Tests and Results

@Test
public void test3() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("v2/day06.xml");
    // 注意:getBean获取的是cat
    IIntroduce introduce = ctx.getBean("cat", IIntroduce.class);
    introduce.sayIntroduce();
}
Copy the code

- the introduction ofCopy the code

3. Summary

This article mainly reviews the configuration of SCHEMa-based AOP, which is based on configuration files. Of course, there are a lot of knowledge points involved here, but this is a brief introduction. For more information, you can refer to the official Spring documentation.