Location>code7788 >text

spring - annotation-based configuration bean, dynamic proxy, AOP notes

Popularity:228 ℃/2024-10-16 12:50:28

 

The use of jdk8, spring framework in the download of jar packages can be searched for yourself!

Annotate the jar packages used.

 

 

60, Annotated Configuration Bean Quickstart

 

Basic Introduction

 

Code Structure:

 

package ;

import ;

/*
* :: Use @Repository to identify the class as a repository, a persistence class/object.
*/
@Repository
public class UserDao {
}

 

package ;

import ;

/*
 * :: Use @Service to identify the class as a Service class/object
*/
@Service
public class UserService {
}

 

package ;

import ;

/*
 * Use @Controller to identify the class as a Controller, usually the class is a Servlet.
*/
@Controller
public class UserAction {
}

 

package ;

import ;

/*
 * Using @Component to identify the class as a component is a generic annotation
*/
@Component
public class MyComponent {
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance" xmlns:util="/schema/util"
       xmlns:context="/schema/context"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/util /schema/util/ /schema/context /schema/context/">
    <!--Configuring packages for containers to scan
    Teacher's explanation
    1. component-scan scans the classes under the specified package and creates objects for the container.
    2. base-package Specifies the package to be scanned.
    3. meaning that when the spring container is created/initialized, it scans all the classes under the package.
       The implication is that when the spring container is created/initialized, it scans the package for all annotated @Controller / @Service / @Respository / @Component classes.
       Instantiate them, generate the objects, and put them into the ioc container.
    4. resource-pattern="User*.class" means that it will only scan for classes that start with User and its sub-packages.

-->
    <context:component-scan base-package="" />
</beans>

 

package ;

import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;

public class SpringBeanTest {

    //Configuring Beans via Annotations
    @Test
    public void setBeanByAnnotation() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        UserDao userDao = (UserDao.class);
        UserService userService = (UserService.class);
        UserAction userAction = (UserAction.class);
        MyComponent myComponent = (MyComponent.class);

        ("userDao=" + userDao);
        ("userService=" + userService);
        ("userAction=" + userAction);
        ("myComponent=" + myComponent);

        ("ok");

    }
}

 

Run results:

 

63, Notes and Details

4, resource-pattern="User*.class" means only scanning and its sub-packages under the User head of the class, this and the third point to remember on their own.

 

There are 3 other considerations that are put in the code, which are which annotations to exclude , which annotations to specify to scan, and what can be used to specify the id value after marking the annotation.

The code structure remains unchanged,, and

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance" xmlns:util="/schema/util"
       xmlns:context="/schema/context"
       xmlns:contect="/schema/c"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/util /schema/util/ /schema/context /schema/context/">
    <!--Configuring packages for containers to scan
    Teacher's explanation
    1. component-scan scans the classes under the specified package and creates objects for the container.
    2. base-package Specifies the package to be scanned.
    3. meaning that when the spring container is created/initialized, it scans all the classes under the package.
       The implication is that when the spring container is created/initialized, it scans the package for all annotated @Controller / @Service / @Respository / @Component classes.
       Instantiate them, generate the objects, and put them into the ioc container.
    4. resource-pattern="User*.class" means that it will only scan for classes that start with User and its sub-packages.
-->
<!--    <context:component-scan base-package=""/>-->

    <!--
        Requirement: If we want to exclude a certain type of annotation under a certain package/subpackage, we can specify it via exclude-filter
        1. context:exclude-filter specifies which classes to exclude
        2. type specifies the exclusion method annotation means exclude by annotation
        3. expression="" specifies the full path of the annotation to be excluded.
-->
<!--    <context:component-scan base-package="">-->
<!--        <context:exclude-filter type="annotation" expression=""/>-->
<!--    </context:component-scan>-->

    <!--
        Requirement: If we want to scan some annotations under a package/subpackage according to our own rules, we can use include-filter with
        1. use-default-filters="false" means don't use the default filtering/scanning mechanism.
        2. context:include-filter indicates which classes to scan.
        3. type="annotation" Scan/filter by annotation
        4. expression="" specifies the full path of the annotations to be scanned
-->
    <context:component-scan base-package="" use-default-filters="false">
        <context:include-filter type="annotation" expression=""/>
        <context:include-filter type="annotation" expression=""/>
    </context:component-scan>
</beans>

 

package ;

import ;

/*
* Use @Repository to identify the class as a Repository, a persistence class/object.
* 1,markup annotated with the first lowercase letter of the class name as the value of the id (default)
* 2,value = "hspUserDao" Use the specified hspUserDao as the id of the UserDao object.
*/
@Repository(value = "hspUserDao")
public class UserDao {
}

 

package ;

import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;

public class SpringBeanTest {

    //Configuring Beans via Annotations
    @Test
    public void setBeanByAnnotation() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        UserDao userDao = (UserDao.class);
        //Default: After marking the annotation, the first lowercase letter of the class name is used as the value of the id. The value attribute of the annotation can also be used to specify the id value, and value can be omitted.
        ("userDao=" + userDao);

        UserService userService = (UserService.class);
        UserAction userAction = (UserAction.class);
        MyComponent myComponent = (MyComponent.class);

        ("userService=" + userService);
        ("userAction=" + userAction);
        ("myComponent=" + myComponent);

        ("ok");

    }
}

 

Debug results:

Test the last note by placing a breakpoint and then Debug. Tap ioc -- beanFactory -- singletonObjects to see the

 

68, their own implementation of Spring annotations to configure the bean mechanism

 

 

Thought Analysis:

 

 

Code Structure:

The four java files in the component package are the code from the previous note, unchanged.

 

package ;

import ;
import ;
import ;
import ;

/**
 * @Target is used to modify an Annotation definition to specify which program elements the modified Annotation can be used to modify.
 * @Retention can only be used to modify an Annotation definition to specify how long the Annotation can be retained.
 * 1. @Target() specifies that our ComponentScan annotation can modify Type program elements.
 * 2. @Retention() specifies that the ComponentScan annotation Retention range.
      Indicates that the compiler will record the annotation in the class file and get it through reflection when running the Java program.
 * 3. String value() default ""; means ComponentScan can pass in value.
*/
@Target()
@Retention()
public @interface ComponentScan {
    String value() default "";
}

 

package ;

/**
 * This is a configuration class that acts like our native spring container configuration file.
*/
@ComponentScan(value = "")
public class HspSpringConfig {
}

 

package ;

import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;

/**
 * The HspSpringApplicationContext class acts like the Spring native ioc container.
*/

public class HspSpringApplicationContext {
    private Class configClass;
    //The ioc I'm storing is the object created by reflection (based on the annotation approach)
    private final ConcurrentHashMap<String, Object> ioc =
            new ConcurrentHashMap<>();

    //constructor
    public HspSpringApplicationContext(Class configClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        this.configClass = configClass;
        //("=" + );
        //Getting packages to scan
//1. First get the HspSpringConfig configuration @ComponentScan(value = "")
        ComponentScan componentScan =
                (ComponentScan)this.(ComponentScan.class);
        //2. through the componentScan value = > that is, to scan the package
        String path = ();
        ("Packages to scan = " + path);

        //Get all resources under the package to be scanned (class .class)
//1. Get the class loader
        ClassLoader classLoader =
                HspSpringApplicationContext.class.getClassLoader();
        //2. Get the resources of the package to be scanned through the class loader url=" something like a path
//Be sure to replace . Replace / with /.
        path = (".","/");
        URL resource =
                ("com/hspedu/spring/component");
        ("resource=" + resource);

        //3. Iterate through the files under the resource (.class) path to be loaded =>io
        File file = new File(());
        if (()) {
            File[] files = ();
            for (File f : files) {
                ("=============");
                ("=" + ());
                //D:\javaProjects\Spring\spring5\out\production\spring5\com\hspedu\spring\component\
                //get
                String fileAbsolutePath = ();
                //Here we're only dealing with .class files
                if ((".class")) {
                    //1. Get the class name
                    String className =
                            (("\\") + 1, (".class"));
                    //("className=" + className);
                    //2. Get the full path of the class (full class name).
//Teacher Interpretation ("/", ".") => .
                    String classFullName = ("/", ".") + "." + className;
                    ("classFullName=" + classFullName);

                    //3. To determine whether the class needs to be injected into the container, see if the class has the annotation @Component @Service...
//At this point, we get the old Class object of the class
//Class clazz = (classFullName)
                    //Teachers talk about it.
//1. Class clazz = (classFullName) can be loaded by reflection.
//2. (classFullName); can reflect the class Class
//3. The difference is: the above method calls the static method of the incoming class, while the following method does not.
                    Class<?> aClass = (classFullName);
                    //4. () Determines if the class has @Component
                    if ((Component.class) ||
                            (Controller.class) ||
                            (Service.class) ||
                            (Repository.class)) {

                        //Here the teacher demonstrates a Component annotation to specify the value, assigned ids
//The teacher just demonstrated the mechanism.

//At this point the object can be reflected and put into a container
                        Class<?> clazz = (classFullName);
                        Object instance = ();
                        //into the container, and lowercase the first letter of the class name as the id.
//StringUtils
                        ((className) , instance);
                    }
                }
            }
        }
    }

    //Write a method to return a pair of objects in the container
    public Object getBean(String name) {
        return (name);
    }
}

 

package ;

import ;
import ;
import ;
import ;


public class HspSpringApplicationContextTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        HspSpringApplicationContext ioc =
                new HspSpringApplicationContext(HspSpringConfig.class);

        UserAction userAction = (UserAction) ("userAction");
        ("userAction" + userAction);

        MyComponent myComponent = (MyComponent) ("myComponent");
        ("myComponent" + myComponent);

        UserService userService = (UserService) ("userService");
        ("userService=" + userService);

        UserDao userDao = (UserDao) ("userDao");
        ("userDao=" + userDao);

        ("ok");
    }
}

 

Debug results:

 

Run results:

 

76,Auto Assembly @Autowired

Code Structure.

 

package ;

import ;

/*
 * :: Use @Service to identify the class as a Service class/object
*/
@Service
public class UserService {
    public void hi() {
        ("UserService hi()~");
    }
}

 

package ;

import ;
import ;
import sun.;

/*
 * Use @Controller to identify the class as a Controller, usually the class is a Servlet.
*/
@Controller()
public class UserAction {
    //xml configuration ref
//Teacher notes @Autowired
//1) Look up the type of the component to be assembled in the IOC container, and if there is a unique bean match (by type), assemble using that bean
//2) If the bean corresponding to the type to be assembled has more than one bean in the IOC container, then use the property name of the property to be assembled as the id value and then lookup.
//  Assemble if found, throw an exception if not
    @Autowired
    //private UserService userService;
    private UserService userService200;

    public void sayOk() {
//        ("=" + userService);
//        ("userService property of userAction assembly = " + userService);
        ("userService200 property of userAction assembly = " + userService200);
        //();
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance" xmlns:util="/schema/util"
       xmlns:context="/schema/context"
       xmlns:contect="/schema/c"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/util /schema/util/ /schema/context /schema/context/">
   <context:component-scan
           base-package=""/>

   <!--Configure two UserService objects-->
   <bean class="" id="userService200"/>
   <bean class="" id="userService300"/>
</beans>

 

package ;

import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;

public class SpringBeanTest {

    //Configuring Beans via Annotations
    @Test
    public void setProByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        UserService userService = ("userService", UserService.class);
        ("userService in ioc container = " + userService);

        UserService userService200 = ("userService200", UserService.class);
        ("userService200 in ioc container = " + userService200);

        UserAction userAction = ("userAction", UserAction.class);
        //("userAction in ioc container=" + userAction);
        ();

    }
}

 

Results.

 

80,Auto-assembly@Resource

The structure of the code is the same as in the previous section.

package ;

import ;
import ;
import sun.;

import ;

/*
 * Use @Controller to identify the class as a Controller, usually the class is a Servlet.
*/
@Controller()
public class UserAction {
    ///Teacher Note @Resource
//1) @Resource has two attributes is more important, divided into name and type, Spring will @Resource annotation name attribute is resolved to the name of the bean, the name of the bean.
//  The type attribute resolves to the type of the bean. So if you use the name attribute, you use the byName auto-injection policy, and the
//  The byType auto-injection policy is used when using the type attribute.
//  For example, @Resource(name = "userService") means assembling the id=userService object.
//  For example, @Resource(type = ) means to assemble by type, which requires that there can only be one object of this type in the container.
//2) If @Resource doesn't specify name and type, then use the byName injection strategy first.
//   If it doesn't match, use the byType strategy again, and if none of them work, an error will be reported

//=================================
    //Teacher's note: The @Autowired + @Qualifier(value = "userService02") combination also accomplishes specifying a name/id for autowiring.
//Specify the id to assemble, also use @Autowired and @Qualifier(value = "userService02")
// At this point, is the assembly id=userService02 , need both annotations need to be written, theIt's simpler to use @Resource(name="userSerice200")
//@Resource(name="userService200") @Resource(type = UserService.class) private UserService userService400; public void sayOk() { // ("=" + userService); // ("userService property of userAction assembly = " + userService); ("userService property of userAction assembly = " + userService400); (); } }

 

package ;

import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;

public class SpringBeanTest {

    //Configuring Beans via Annotations
    @Test
    public void setProByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        UserService userService = ("userService", UserService.class);
        ("userService in ioc container = " + userService);

//        UserService userService200 = ("userService200", );
//        ("userService200 in ioc container=" + userService200);

        UserAction userAction = ("userAction", UserAction.class);
        //("userAction in ioc container=" + userAction);
        ();

    }
}

 

Results.

 

82, Generic Dependency Injection

 

Relationship diagram for each class.

Class Relationship Diagram Explanation.

If BookService want to use BookDao, can be assembled to the BookDao attribute BookService up, but the problem is that there are many subclasses under the BaseService and BaseDao, write up a lot of trouble, so spring provides a generic dependency injection, that is, the BaseDao assembly to the BaseService up, just formal assembly, will not instantiate their objects, the real realization is the subclass object, in the time to get the BookService, pass in the generic type BaseService up, just the form of assembly, will not instantiate their objects, the real realization of the subclass object, in the BookService when you get, pass in the generic & lt; Book & gt;, according to the generic dependency on the assembly, the BookDao object will automatically be assembled to the BookService up!

The underlying mechanism is : Reflection + Annotation + IO + String + Generics.

 

Code Structure.

 

package ;

public class Book {
}

 

package ;

public class Phone {
}

 

package ;

//Customized Generic Classes
public abstract class BaseDao<T> {
    public abstract void save();
}

 

package ;

import ;

@Repository
public class BookDao extends BaseDao<Book>{
    @Override
    public void save() {
        ("BookDao's save()...");
    }
}

 

package ;

import ;

@Repository
public class PhoneDao extends BaseDao<Phone>{
    @Override
    public void save() {
        ("PhoneDao save()");
    }
}

 

package ;

import ;

public class BaseService<T> {

    @Autowired
    private BaseDao<T> baseDao;

    public void save(){
        ();
    }
}

 

package ;

import ;

@Service
public class BookService extends BaseService<Book>{
    //It doesn't write the attribute
}

 

package ;

import ;

@Service
public class PhoneService extends BaseService<Phone>{
    //is to assemble the PhoneDao object to the PhoneService, spring's underlying support for the
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance" xmlns:util="/schema/util"
       xmlns:context="/schema/context"
       xmlns:contect="/schema/c"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/util /schema/util/ /schema/context /schema/context/">

   <context:component-scan
           base-package=""/>
</beans>

 

package ;

import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;

public class SpringBeanTest {

    //Configuring Beans with Generic Dependencies
    @Test
    public void setProByDependencyInjection() throws BeansException {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");
        PhoneService phoneService = ("phoneService", PhoneService.class);
        ();

    }
}

 

Results.

 

86, Traditional Approaches to Addressing Dynamic Agent Needs

 

Code Structure:

 

connector

package .proxy2;

//The interface has the run method
public interface Vehicle {
    public void run();
}

 

package .proxy2;

public class Car implements Vehicle{
    @Override
    public void run() {
        ("The transportation is up and running...");
        ("Small cars running on the highway...");
        ("The transportation stopped working...");
    }
}

 

package .proxy2;

public class Ship implements Vehicle{
    @Override
    public void run() {
        ("The transportation is up and running...");
        ("Big ships on the water running...");
        ("The transportation stopped working...");
    }
}

 

package .proxy2;

import ;

public class TestVehicle {
    @Test
    public void run(){
        //OOP Basics
        Vehicle vehicle = new Car();
        ();
        ("----------------");
        Vehicle vehicle1 = new Ship();
        ();
    }
}

 

Run results:

 

If you want to change a few objects, you can only change them one by one, without unified management.

 

87, Dynamic Agent Solution Requirements

Dynamic proxy solution idea, in the call method, use the reflection mechanism, according to the method to decide which object to call the method

 

Code Structure:

is unchanged, and the dynamic agent mechanism is debugged.

 

package .proxy2;

public class Car implements Vehicle{
    @Override
    public void run() {
        //("Transportation is up and running...") ;
        ("Small cars running on the highway..."));
        //("Transportation has stopped running...") ;
    }
}

 

package .proxy2;

public class Ship implements Vehicle{
    @Override
    public void run() {
        //("Transportation is up and running...") ;
        ("Big ships running on the water..."));
        //("Transportation has stopped running...") ;
    }
}

 

package .proxy2;

import ;
import ;
import ;

/**
 * VehicleProxyProvider This class can return a proxy object.
*/
public class VehicleProxyProvider {
    //Define a property
//target_vehicle Indicates the real object to be executed.
//This object implements the Vehicle interface
    private Vehicle target_vehicle;

    //constructor
    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }

    //Write a method that returns a proxy object, which can be called through reflection to the methods of the proxy object.
//Teacher Interpretation
//1. This method is very important and can be difficult to understand.
    public Vehicle getProxy() {

        //Get class loader
        ClassLoader classLoader =
                target_vehicle.getClass().getClassLoader();

        //Get the interface information of the object to be proxied/executed, the bottom is to complete the call through the interface.
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();

        //Create InvocationHandler object
//Since InvocationHandler is an interface, we can create it by means of an anonymous object

        InvocationHandler invocationHandler = new InvocationHandler() {
            /**
             * The invoke method is to be called in the future when executing our target_vehicle's methods.
             * o: represents the proxy object
             * method: is the method that will be called when the method is invoked through the proxy object proxy.run()
             * args: the arguments passed in to call proxy.run(xx).
             * return: the result after the proxy.run(xx) is executed.
*/
            @Override
            public Object invoke(Object o, Method method, Object[] args)
                    throws Throwable {
                ("Transportation is up and running ....");
                //Here is our reflection base => OOP
//method be?: public abstract void .()
                //target_vehicle is ? Ship object
//args is null
//Here, through reflection + dynamic binding mechanism, the methods of the proxied object will be executed
//Returns when execution is complete
                Object result = (target_vehicle, args);
                ("Transportation has stopped running ....");
                return result;
            }
        };
        /**

          public static Object newProxyInstance(ClassLoader loader,
                                          Class<? >[] interfaces,
                                          InvocationHandler h)
          Teacher Interpretation
          1. () can return a proxy object
          2. ClassLoader loader: the class loader. 3.
          3. Class<? >[] interfaces is the interface information of the object to be proxied in the future.
          4. InvocationHandler h The invocation handler/object has a very important method, invoke.
*/
        Vehicle proxy =
                (Vehicle) (classLoader, interfaces, invocationHandler);
        return proxy;
    }
}

 

package .proxy2;

import ;

public class TestVehicle {
    @Test
    public void run(){
        //OOP Basics
        Vehicle vehicle = new Car();

        //Create the VehicleProxyProvider object, and the object we passed in to proxy.
        VehicleProxyProvider vehicleProxyProvider =
                new VehicleProxyProvider(vehicle);

        //Get the proxy object, which can execute methods on behalf of the proxy
//Teacher Interpretation
//1. porxy compilation type Vehicle
//2. run type is a proxy type class . $Proxy9
        Vehicle proxy = ();
        ("The compiled type of proxy is Vehicle.");
        ("The run type of the proxy is " + ());
        //The following Lao Han will give you to explain / debug how to execute to the proxy object public Object invoke(Object o, Method method, Object[] args)
//That's it. The compile type of proxy is Vehicle, the run type is class . $Proxy9
//So when the run method is executed, the invoke of the proxy is executed.

//How to represent dynamic [1. proxied objects 2. methods].
//1. The proxy run type is . $Proxy0 This type is transformed to Vehicle
// So you can call Vehicle's interface method
//2. will be called when run() is executed, and according to Java's dynamic binding mechanism, this time it will call Car's run() directly, which will be called when the run() is executed.
// Instead, it is the invoke method of the invocationHandler of the proxy object (!!!!!!).
//3. The invoke method uses the reflection mechanism to invoke the run() method. note that this run method can also be any other method of the Vehicle).
// This is where the pre-processing and post-processing can be done before the run() method is called
//4. That is, the target_vehicle run type of the proxy implements the Vehicle interface as long as it
// The first thing you can do is to call different methods, which are dynamic and changing, and this is done at the bottom by using reflection.
        ();
    }
}

 

Run results:

 

91, Dynamic Agents in Depth (Traditional Approach Solution)

 

The traditional idea of solving the problem in each method of[Before the implementation process, empress]Output log.

 

Code Structure:

 

package ;

//connector
public interface SmartAnimalable {

    //look for a draw (chess)
    float getSum(float i, float j);

    //look for a way out
    float getSub(float i, float j);
}

 

package ;

public class SmartDog implements SmartAnimalable{
    @Override
    public float getSum(float i, float j) {
        ("log-method-name-getSum-arguments " + i + " " + j);
        float result = i + j;
        ("The method internally prints result = " + result);
        ("log-method-name-getSum-result result= " + result);
        return result;
    }

    @Override
    public float getSub(float i, float j) {
        ("log-method-name-getSub-arguments " + i + " " + j);
        float result = i - j;
        ("The method internally prints result = " + result);
        ("log-method-name-getSub-result result= " + result);
        return result;
    }
}

 

package ;

import ;

public class AopTest {
    @Test
    public void smartDogTest() {
        SmartAnimalable smartAnimalable = new SmartDog();
        (10, 2);
        ("===========================");
        (10, 2);
    }
}

 

Run results:

 

 

93, Dynamic Agents in Depth (Dynamic Agent Approach Solution)

Code Structure:

(math.) invariant

 

package ;

public class SmartDog implements SmartAnimalable{
    @Override
    public float getSum(float i, float j) {
        //("log-method-name-getSum-argument " + i + " " + j);
        float result = i + j;
        ("The method internally prints result = " + result);
        //("log-method-name-getSum-result-result= " + result);
        return result;
    }

    @Override
    public float getSub(float i, float j) {
        //("log-method-name-getSub-argument " + i + " " + j);
        float result = i - j;
        ("The method internally prints result = " + result);
        //("log-method-name-getSub-result-result= " + result);
        return result;
    }
}

 

package ;

import ;
import ;
import ;
import ;

/**
 * :: Can return a dynamic proxy object that can execute the methods of the SmartDog object.
*/
public class MyProxyProvider {
    //Define the target object we want to execute, which needs to implement SmartAnimalable.
    private SmartAnimalable target_obj;

    //constructor
    public MyProxyProvider(SmartAnimalable target_obj) {
        this.target_obj = target_obj;
    }

    //method, which returns a proxy object that can execute the target object's
    public SmartAnimalable getProxy() {

        //1. First-come-first-served class loaders/objects
        ClassLoader classLoader = target_obj.getClass().getClassLoader();

        //2. get the interface information of the target object to be executed
        Class<?>[] interfaces = target_obj.getClass().getInterfaces();

        //3. Create InvocationHandler
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                try {
                    ("method-before-execution-log-method-name-" + () + "-args "
                            + (args)).//Here, from AOP, it's a cross-cutting concern-preceding notification
//Calling Methods Using Reflection
                    result = (target_obj, args);
                    ("Method execution ended normally - log - method name - " + () + "- result result= "
                            + result);//From the AOP point of view, there is also a cross-cutting concern-return notification

                } catch (Exception e) {
                    ();
                    //If an exception occurs when the method is executed by reflection, it goes to catch{}
                    ("method-execution-exception-log-method-name-" + ()
                            + "- Exception type = " + ().getName());//From the AOP point of view, there is also a cross-cutting concern - exception notification
                } finally {//Whether you get an exception or not, you'll eventually get to finally{}
//From an AOP point of view, it is also a cross-cutting concern - the final notification
                    ("method-final-end-log-method-name-" + ());
                }

                return result;
            }
        };
        //Creating Proxy Objects
        SmartAnimalable proxy =
                (SmartAnimalable) (classLoader, interfaces, invocationHandler);
        return proxy;
    }
}

 

package ;

import ;

public class AopTest {
    @Test
    public void smartDogTestByProxy() {
        SmartAnimalable smartAnimalable = new SmartDog();

        //Create the MyProxyProvider object, and the object we passed in to proxy.
        MyProxyProvider myProxyProvider =
                new MyProxyProvider(smartAnimalable);

        //Get a proxy object that can execute methods on behalf of the proxy.
        SmartAnimalable proxy =
                ();

        (10, 2);
        ("====================");
        (10, 2);
    }
}

 

Run results:

 

95, AOP Quick Start

Basic Introduction

You can cut the method in the facet class (think of it as a knife) into any one of the locations in class A and B.

 

 

 

 

Case in point:

 

 

Code Structure:

 

package ;

//connector
public interface SmartAnimalable {
    //look for a draw (chess)
    float getSum(float i, float j);
    //look for a way out
    float getSub(float i, float j);
}

 

package ;

import ;

@Component //Using @Component Inject SmartDog into the spring container when it starts up
public class SmartDog implements SmartAnimalable {
    @Override
    public float getSum(float i, float j) {
        float result = i + j;
        //int res = 9 / 0; //Simulating an arithmetic exception
        ("Method internally prints result = " + result);
        return result;
    }

    @Override
    public float getSub(float i, float j) {
        float result = i - j;
        ("The method internally prints result = " + result);
        return result;
    }
}

 

package ;

import ;
import ;
import ;
import .*;
import ;
import ;
import ;

import ;
import ;
import ;

/**
 * :: A facade class, similar to the MyProxyProvider we used to write ourselves, but much more powerful.
*/
//@Order(value = 2)//Indicates the order of execution of the cutover class, the smaller the value, the higher the priority.
@Aspect //Representation is a faceted class [underpinning of underlying faceted programming (dynamic proxies + reflection + dynamic binding...)]
@Component //The SmartAnimalAspect is injected into the container.
public class SmartAnimalAspect {

    //Define an entry point that can be directly referenced when used later, improving reusability.
    @Pointcut(value = "execution(public float (float, float)))")
    public void myPointCut() {
    }

    /**
     * Teacher's explanation
     * 1. @Before means before notification: that is, before our target object executes the method
     * 2. value = "execution(public float (float, float)
     * Specifies which method of which class to cut to in the form of: access modifier return type class name. Method name (list of formal parameters).
     * 3. showBeginLog method can be understood as an entry method, the method name can be specified by the programmer For example: showBeginLog * 4. JoinPoint joinPoint in the class.
     * 4. JoinPoint joinPoint in the underlying implementation, by the AspectJ cutter framework, will be passed to the entry method joinPoint object * , through this method, the programmer will be able to joinPoint object * , the programmer will be able to joinPoint object.
     * , through this method, the programmer can obtain the relevant information * * and the programmers can use the method to access the information.
     * *
     * , through which the programmer can obtain relevant information *@param joinPoint
     */

    //Wish to cut the f1 method to execute before SmartDog-getSum - prenotification
//@Before(value = "execution(public float (float, float))")
    //Here we use the defined entry point
    @Before(value = "myPointCut()")
    public void showBeginLog(JoinPoint joinPoint) {
        //The method signature can be obtained from the joinPoint object.
        Signature signature = ();
        ("SmartAnimalAspect - cut class showBeginLog() [myPointCut() used] - before method execution - log - method name - " + () + "- parameters "
                + (()));
    }

    //Return notification: i.e., cut the showSuccessEndLog method to where the target object's method has finished executing normally
//Lao Han's interpretation.
//1. if we want to return the result of the execution of the target method to the cut-in method
//2. you can add attributes to @AfterReturning, such as returning = "res".
//3. Also add Object res to the entry method.
//4. Note: returning = "res" is the same as the name of res in Object res.
//@AfterReturning(value = "execution(public float (float, float))", returning = "res")
    //Use of entry points
    @AfterReturning(value = "myPointCut()", returning = "res")
    public void showSuccessEndLog(JoinPoint joinPoint, Object res) {
        Signature signature = ();
        ("SmartAnimalAspect-Cutting class showSuccessEndLog()-method-execution-ended-normal-log-method-name-" + () + " The returned result is =" + res);
    }


    //Exception notification: i.e., cut the showExceptionLog method to the target object method to execute the catch{} if an exception occurs.
//@AfterThrowing(value = "execution(public float (float, float))", throwing = "throwable")
    //Direct use of entry point expressions
    @AfterThrowing(value = "myPointCut()", throwing = "throwable")
    public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {
        Signature signature = ();
        ("SmartAnimalAspect-Cutting class showExceptionLog()-MethodExecutionException-Log-MethodName-" + () + " ExceptionMessage=" + throwable);
    }

    //Final notification: i.e., cut the showFinallyEndLog method into the target method execution (whether or not an exception occurs, execute finally{})
//@After(value = "execution(public float (float, float))")
    //Direct use of entry points
    @After(value = "myPointCut()")
    public void showFinallyEndLog(JoinPoint joinPoint) {
        Signature signature = ();
        ("SmartAnimalAspect-Cutting class showFinallyEndLog()-method-finally-executed-log-method-name-" + ());
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance"
       xmlns:context="/schema/context"
       xmlns:aop="/schema/aop"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/context /schema/context/ /schema/aop /schema/aop/">

   <context:component-scan
           base-package=""/>

   <!-- Enabling annotation-based AOP-->
   <aop:aspectj-autoproxy/>
</beans>

 

package ;

import ;
import ;
import ;

public class AopAspectjTest {
    @Test
    public void smartDogTestByProxy(){
        //Getting the spring container
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        //Here we need to get the injected SmartDog object - the proxy object - by its interface type.
        SmartAnimalable smartAnimalable =
                (SmartAnimalable.class);

        (10, 2);
//        ("smartAnimalable run type ="
//                + ());//class .$Proxy17
    }
}

 

Run results:

 

The code getBean() is also equivalent to getProxy() in dynamic proxies, and returns the proxy object.

 

108, after-school assignments

 

This question uses detail 5 and the cut-in expression from the next section.

The details:

 

Code Structure:

Unchanged, as in the previous section.

 

connector

package ;

public interface UsbInterface {
    public void work();
}

package ;

import ;

@Component//Injecting a Phone object as a component into a container
public class Phone implements UsbInterface{
    @Override
    public void work() {
        ("The cell phone is starting to work...");
    }

}

 

package ;

import ;

@Component//Injecting a Camera object as a component into a container
public class Camera implements UsbInterface{
    @Override
    public void work() {
        ("The camera is starting to work...");
    }
}

 

package ;

import ;
import ;
import ;
import .*;
import ;
import ;
import ;

import ;
import ;
import ;

/**
 * :: A facade class, similar to the MyProxyProvider we used to write ourselves, but much more powerful.
*/
//@Order(value = 2)//Indicates the order of execution of the cutover class, the smaller the value, the higher the priority.
@Aspect //Representation is a faceted class [underpinning of underlying faceted programming (dynamic proxies + reflection + dynamic binding...)]
@Component //The SmartAnimalAspect is injected into the container.
public class SmartAnimalAspect {

    @Before(value = "execution(public void ()) || execution(public void ())")
    public void hi(JoinPoint joinPoint) {
        Signature signature = ();
        ("The hi()-executed target method of the cutout class -" + ());
    }
}

 

package ;

import ;
import ;
import ;

public class AopAspectjTest {
    @Test
    public void smartDogTestByProxy(){
        //Getting the spring container
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        //Here we can't get to the injected Phone object - which is the proxy object - through the interface type, because both the Phone object and the Camera object implement the UsbInterface interface.
//        UsbInterface bean = ();
//        ();

        UsbInterface phone = (UsbInterface) ("phone");
        UsbInterface camera = (UsbInterface) ("camera");

        ();
        ("---------------------");
        ();
    }
}

 

Run results:

 

109, cut-in expression

Specific use:

 

The details:

Detail 3 Code Structure:

Same as the previous section.

 

package ;

import ;

@Component//Injecting a Phone object as a component into a container
public class Car {
    public void run(){
        ("The little car is running...");
    }
}

 

package ;

import ;
import ;
import ;
import .*;
import ;
import ;
import ;

import ;
import ;
import ;

/**
 * :: A facade class, similar to the MyProxyProvider we used to write ourselves, but much more powerful.
*/
//@Order(value = 2)//Indicates the order of execution of the cutover class, the smaller the value, the higher the priority.
@Aspect //Representation is a faceted class [underpinning of underlying faceted programming (dynamic proxies + reflection + dynamic binding...)]
@Component //The SmartAnimalAspect is injected into the container.
public class SmartAnimalAspect {

    //Configure a prenotification for Car
    @Before(value = "execution(public void ())")
    public void ok1(JoinPoint joinPoint) {
        Signature signature = ();
        ("ok1()-executed target method of the cutover class -" + ());
    }
}

 

package ;

import ;
import ;
import ;

public class AopAspectjTest {
    @Test
    public void smartDogTestByProxy(){
        //Getting the spring container
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        //Car objects are still proxy objects
        Car car = (Car.class);
        ();
        ("The run type of car = " + ());
    }
}

 

Run results:

 

115, Surrounding Notice

 

Modify the code in Section 95 by deleting it and re-copying it as , and modifying it.

 

package ;


import ;
import .*;
import ;

import ;
import ;

/**
 * @author Han Soon-pyeong
 *@version 1.0
 * :: A cutover class, similar to the MyProxyProvider we used to write ourselves, but much more powerful.
*/
@Aspect //Representation is a faceted class [underpinning of underlying faceted programming (dynamic proxies + reflection + dynamic binding...)]
@Component //SmartAnimalAspect2 is injected into the container.
public class SmartAnimalAspect2 {

    //Demonstrate the use of wrap-around notifications-understand
//Teacher Interpretation
//1. @Around: Indicates that this is a surround notification [fulfills the function of the other four notifications]
//2. value = "execution(public float (float, float)) entry point expression
//3. doAround indicates the method to be cut into - call structure try-catch-finally
    @Around(value = "execution(public float (float, float))")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object result = null;
        String methodName = ().getName();
        try {
            //1. Equivalent to front-loaded notification of completion
            Object[] args = ();
            List<Object> argList = (args);
            ("AOP Surrounding Notification [-Pre-Notification]" + methodName + "The method is started - the parameters are:" + argList);
            //Be sure to call () in the wrap-around notification to execute the target method
            result = ();
            //2. Equivalent to returning a notification of completion
            ("AOP wrap-around notification [- return notification]" + methodName + "The method is finished - the result is:" + result);
        } catch (Throwable throwable) {
            //3. The equivalent of an exception notification of completion
            ("AOP wrap-around notification [-Exception notification]" + methodName + "Method threw exception - Exception object:" + throwable);
        } finally {
            //4. Things equivalent to final notice of completion
            ("AOP wrap around notification [- post notification]" + methodName + "The method finally ends..."));
        }
        return result;
    }
}

 

package ;

import ;
import ;
import ;

public class AopAspectjTest {
    @Test
    public void testDoAround() {
        //Getting the spring container
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");


        SmartAnimalable smartAnimalable =
                (SmartAnimalable.class);

        (10, 2);
    }
}

 

Run results:

 

119, AOP based on XML configuration

 

Code Structure:

It's the same as in Section 95, except that you have to pay attention to the name of the package that import introduces.

Commented out the @Component annotation.

 

package ;

import ;
import ;
import ;
import ;
import ;
import ;

import ;

/**
 * @author Han Soon-pyeong
 *@version 1.0
 *
 * This is where we develop a faceted class, but instead of annotating it, we use XML to configure it.
*/
public class SmartAnimalAspect {
    public void showBeginLog(JoinPoint joinPoint) {
        //The method signature can be obtained from the joinPoint object.
        Signature signature = ();
        ("SmartAnimalAspect - XML Configuration - Cutting class showBeginLog() [myPointCut() used] - Before method execution - Log - Method name - " + () + "- Parameters "
                + (()));
    }

    public void showSuccessEndLog(JoinPoint joinPoint, Object res) {
        Signature signature = ();
        ("SmartAnimalAspect-XML Configuration-Cutting Class showSuccessEndLog()-Method Execution Ends Normal-Log-MethodName-" + () + " The returned result is =" + res);
    }


    public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {
        Signature signature = ();
        ("SmartAnimalAspect-XML-Configuration-Cutting-Class showExceptionLog()-MethodExecutionException-Log-MethodName-" + () + " ExceptionMessage=" + throwable);
    }

    public void showFinallyEndLog(JoinPoint joinPoint) {
        Signature signature = ();
        ("SmartAnimalAspect-XML Configuration-Cutting Class showFinallyEndLog()-Method Finalized-Log-Method Name-" + ());
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance"
       xmlns:context="/schema/context"
       xmlns:aop="/schema/aop"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/context /schema/context/ /schema/aop /schema/aop/">

   <!--Use XML configuration to accomplish AOP programming-->
   <!--Configure a faceted class object-bean-->
   <bean class="" id="smartAnimalAspect"/>

   <!--Configuring a SmartDog object-bean-->
   <bean class="" id="smartDog"/>

   <!--Configure cutover classes, details must be introduced xmlns:aop-->
   <aop:config>
      <!--Configuring entry points-->
      <aop:pointcut id="myPointCut" expression="execution(public float (float, float)))"/>

      <!--Here you can specify the object of the cutover, its predecessor, return, exception, and eventual notification.-->
      <aop:aspect ref="smartAnimalAspect" order="10">
         <!--Configuring Pre-Notifications-->
         <aop:before method="showBeginLog" pointcut-ref="myPointCut"/>
         <!--Return notification-->
         <aop:after-returning method="showSuccessEndLog" pointcut-ref="myPointCut" returning="res"/>
         <!--Exception Notification-->
         <aop:after-throwing method="showExceptionLog" pointcut-ref="myPointCut" throwing="throwable"/>
         <!--Final notification-->
         <aop:after method="showFinallyEndLog" pointcut-ref="myPointCut"/>
         <!--Configuring Surround Notifications-->
         <!--<aop:around method=""/>-->
      </aop:aspect>
   </aop:config>
</beans>

 

package ;

import ;
import ;
import ;

public class AopAspectjXMLTest {
    @Test
    public void testDoAround() {
        //Getting the spring container
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");
        SmartAnimalable smartAnimalable =
                (SmartAnimalable.class);
        (10, 2);
    }
}

 

Run results:

 

123, Operations (annotated approach)

 

Code Structure:

 

package ;

public interface Cal {
    public int cal1(int n);
    public int cal2(int n);
}

 

package ;

import ;

@Component//Injecting a MyCal object as a component into a container
public class MyCal implements Cal{
    @Override
    public int cal1(int n) {
        int res = 1;
        for(int i = 1; i <= n; i++) {
            res += i;
        }
        ("cal1 execution result =" + res);
        return res;
    }

    @Override
    public int cal2(int n) {
        int res = 1;
        for(int i = 1; i <= n; i++) {
            res *= i;
        }
        ("cal2 execution result =" + res);
        return res;
    }
}

 

package ;

import ;
import ;
import ;
import ;
import ;
import ;

@Aspect //MyCalAOP is a cutover class
@Component //MyCalAOP/Objects Injected into spring container as a component
public class MyCalAop {

    //preemptive notice
//Note that if the target class and the cutover class are in the same package, you can omit the package name.
//Because cal1 and cal2 methods, both to go to the output of the start of the execution time, so the use of MyCal.
    @Before(value = "execution(public int MyCal.*(int))")
    public void calStart(JoinPoint joinPoint) {
        Signature signature = ();
        (() + " Execution, start of execution = " + ());
    }

    //Return notification
//Note that if the target class and the cutover class are in the same package, you can omit the package name.
//Because cal1 and cal2 methods, both to go to the output of the start of the execution time, so the use of MyCal.
    @AfterReturning(value = "execution(public int MyCal.*(int))")
    public void calEnd(JoinPoint joinPoint) {
        Signature signature = ();
        (() + " Execution, end time = " + ());

    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance"
       xmlns:context="/schema/context"
       xmlns:aop="/schema/aop"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/context /schema/context/ /schema/aop /schema/aop/">

   <!--Scanning specified packages-->
   <context:component-scan
           base-package=""/>

   <!--Enabling annotation-based AOP functionality-->
   <aop:aspectj-autoproxy/>
</beans>

 

package ;

import ;
import ;
import ;

public class TestMyCalAOP {
    @Test
    public void testMyCalByAnnotation() {

        //Getting the spring container
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("");

        Cal cal = (Cal.class);

        cal.cal1(10);
        ("-------------------------");
        cal.cal2(5);
    }
}

 

Run results:

 

124, Operations (XML-based)

Code Structure:

, , as in the previous section, pay attention to the names of the packages introduced.

 

package ;

import ;
import ;


public class MyCalAOP {

    //preemptive notice
    public void calStart(JoinPoint joinPoint) {
        Signature signature = ();
        (() + " Based on XML configuration - execution, start execution time = " + ());

    }

    //Return notification
    public void calEnd(JoinPoint joinPoint) {
        Signature signature = ();
        (() + " Based on XML configuration - execution, end time = " + ());

    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
       xmlns:xsi="http:///2001/XMLSchema-instance" xmlns:aop="/schema/aop"
       xsi:schemaLocation="/schema/beans /schema/beans/ /schema/aop /schema/aop/">

   <!--Configuring MyCalAOP-bean-->
   <bean class="" id="myCalAOP" />

   <!--Configuring MyCal-bean-->
   <bean class="" id="myCal"/>

   <!--Configuring cutover classes-->
   <aop:config>
      <!--Configuring entry point expressions-->
      <aop:pointcut id="myPointCut" expression="execution(public int .*(int))"/>

      <!--Configuration front, return notification-->
      <aop:aspect ref="myCalAOP" order="10">
         <aop:before method="calStart" pointcut-ref="myPointCut"/>

         <aop:after-returning method="calEnd" pointcut-ref="myPointCut"/>
      </aop:aspect>
   </aop:config>
</beans>

 

Run results: