Spring framework - in depth

Keywords: Java Spring Junit xml

1.Spring IOC

IOC Technology: inversion of control, also known as (dependency injection)

Inversion of control: the life cycle of a Bean is not under your control, but is managed by the Spring container.

How does Spring framework utilize IOC? :
Spring container can help us instantiate objects, but it doesn't do DI (dependency injection).

Function:
Build Bean (1)
If there is a dependency between (2) beans, it can automatically inject
Advantages:
Decoupling: low coupling, interface oriented programming

2.Spring AOP

Dynamic agent design pattern
There is no essential difference between the principle and the static agent design mode:
Proxied class, proxy class, proxied class and proxy class are the same interface
The creation process of agent class is different:
Static agent:
Write the agent class by yourself, and the agent class implements the interface by itself
Dynamic agent:
Proxy.newProxyinstance(xx) static method
Dynamic generation of agent classes during program execution
InvocationHandler: contains a reference to the proxied class

AOP: Aspect Oriented Programming

The main functions of agent mode are as follows:
In case of business code failure, cut in additional functions.
Principle: Spring framework has IOC function, so we can use it to configure business Bean. Agent design pattern (dynamic)
Example: AccountServiceImpl
        <bean id="AccountServiceImpl" class="service.AccountServiceImpl"></bean>
Then, the Spring framework uses the dynamic proxy design pattern to create a dynamic proxy object for AccountServiceImpl
Then you can add corresponding functions based on the business methods of AccountServiceImpl.
Spring calls this technology AOP aspect oriented programming, which is actually to cut in additional functions on its business methods without the programmer's knowledge.

 

Use XML configuration to implement specific operations:
To use Spring's AOP function, you need to introduce jar pom.xml.
(2) write your own facets. Very similar to InvocationHandler
Proxy interface: business interface
Proxy class: implements the proxy interface. The proxy class is also called the business implementation class.
Example: class CalFfabImpl implements ICalFab

Code example:

Maven project

Plug in added by pom.xml

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.10</version>
        </dependency>       
 <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
                
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>            

 

Add resource configuration file beans.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- Spring IOC --> 
   <bean id="calFab" class="day02.aop.CalFabImpl"></bean>
   <bean id="selfAspectRef" class="day02.aop.SelfAspect"></bean>
   
   <!-- Spring Aop Configuration section -->
   <aop:config>
           <!-- Configuration section -->
           <aop:aspect ref="selfAspectRef">
               <!-- Pointcuts CalFabImpl Add notification to any method of class -->
               <aop:pointcut expression="execution(* day02.aop.CalFabImpl.*(..))" id="selfPointcut"/>
               <!-- notice -->
               <aop:before method="testBefore" pointcut-ref="selfPointcut"/>
               <aop:after method="testAfter" pointcut-ref="selfPointcut"/>
               <aop:around method="testAround" pointcut-ref="selfPointcut"/>
           </aop:aspect>
   </aop:config>
   
</beans>

 

New interface ICalFab.java

 1 /**
 2  * Service interface
 3  * @author Zhang Ze
 4  */
 5 public interface ICalFab {
 6     
 7     int calFaByLoop(int n);
 8     int calFabByRecursion(int n); 
 9 
10 }

 

New class implementation interface:

/**
 * Business implementation class: represented class
 * @author Zhang Ze
 */
class CalFabImpl implements ICalFab{
    @Override
    public int calFaByLoop(int n) {
        int n1=1,n2= 1,n3=0;
        for (int i = 3; i < n; i++) {
            n3=n1+n2;
            n1=n2;
            n2=n3;
        }
        return n3;
    }
    @Override
    public int calFabByRecursion(int n) {
        if(n==1||n==2) return 1;
        return calFabByRecursion(n-1)+calFabByRecursion(n-2);
        
    }
    
    
}

 

New class: SelfAspect.java

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * Custom functional aspect: implemented with xml configuration.
 * @author Zhang Ze
 *
 */
public class SelfAspect {
    //--Notice: Before Type Advice
    public void testBefore() {
        System.out.println("before do something...");
    }
    //--Notice: after Notification of type
    public void testAfter() {
        System.out.println("after do Something...");
    }
    //-- Notice: Around Execution point around notification method
    public int testAround(ProceedingJoinPoint jp) {
        int result = 0;
        try {
            long start = System.currentTimeMillis();
            result = (int)jp.proceed();    //-- Execute business method
            long end = System.currentTimeMillis();
            System.out.println(end-start+"ms");
        } catch (Throwable e) {
            e.printStackTrace();
        }    
        return result;
    }
} 

 

New calling class: Invoker.java

 

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

/**
 * Invoker class
 * More flexible function entry
 * @author Zhang Ze
 *
 */
public class Invoker {
    public static void main(String[] args) {
        //-- 1. Spring container
        ApplicationContext ctx =
                new ClassPathXmlApplicationContext("application.xml");
        //-- 2. Get business class
        ICalFab calFab= (ICalFab)ctx.getBean("calFab");
        //-- 3. Call business method
        System.out.println(calFab.calFaByLoop(40));
        System.out.println(calFab.calFabByRecursion(40));
        System.out.println(calFab instanceof ICalFab);
        
    }
}

 

 

 

 

Use annotation configuration to achieve specific operations:

(1) Config class to replace xml configuration
@ EnableAspectJAutoProxy / / - enable SpringAop
Enable Spring's IOC function
          @Configuration
          @ComponentScan({"package1","package2"})
(2) write facets.

 

Code example:

New interface ICalFab.java

/**
 * Service interface
 * @author Zhang Ze
 *
 */

public interface ICalFab {
    
    int calFaByLoop(int n);
    int calFabByRecursion(int n); 

}

 

New implementation class CalFabImpl.java

import org.springframework.stereotype.Component;

/**
 * Business implementation class: represented class
 * @author Zhang Ze
 */
@Component    //-- Spring IOC
class CalFabImpl implements ICalFab{
    @Override
    public int calFaByLoop(int n) {
        int n1=1,n2= 1,n3=0;
        for (int i = 3; i < n; i++) {
            n3=n1+n2;
            n1=n2;
            n2=n3;
        }
        return n3;
    }
    @Override
    public int calFabByRecursion(int n) {
        if(n==1||n==2) return 1;
        return calFabByRecursion(n-1)+calFabByRecursion(n-2);
        
    }
    
    
}

 

New configuration class AppConfig.java

 

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * Configuration class
 * @author Zhang Ze
 * Realize IOC function
 * 
 */
@Configuration
@EnableAspectJAutoProxy //-- Enable SpringAop Function
@ComponentScan("day.annocation")//-- Package name
public class AppConfig {
//    @Bean
//    public ICalFab calFabBean() {
//        return new CalFabImpl();
//    }
}

 

 

 

 

New class: SelfAspect.java

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * Customize cut with dimensions
 * @author Zhang Ze
 *
 */
@Aspect
@Component
public class SelfAspect {
    
    //-- 1. Custom tangent point, specifying the location of the target method
    @Pointcut("execution(* day02.annocation.CalFabImpl.*(..))")
    public void selfPointcut() {
        
    }
    //-- 2. notice
    @Before("selfPointcut()")
    public void testBefore() {
        System.out.println("before do something...");
    }
    
    @After("selfPointcut()")
    public void testAfter() {
        System.out.println("After do something...");
    }
    @Around("selfPointcut()")
    public int testAround(ProceedingJoinPoint jp) {
        int result = 0;
        try {
            long start = System.currentTimeMillis();
            result = (int)jp.proceed();    //-- Execute business method
            long end = System.currentTimeMillis();
            System.out.println(end-start+"ms");
        } catch (Throwable e) {
            e.printStackTrace();
        }    
        return result;
    }
}

 

New class: Invoker.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Invoker {
    public static void main(String[] args) {
        //-- 1.structure Spring container
        ApplicationContext ctx = 
                new AnnotationConfigApplicationContext(AppConfig.class);
        //-- 2.Obtain Beans
        ICalFab calFab =(ICalFab)ctx.getBean("calFabImpl");//-- The default is lowercase
        calFab.calFabByRecursion(40);
        
        //-- Web Instantiate a Spring Container, in Web Shut down when the server is shut down Spring container
        //-- Servlet Monitoring
        //-- Container closure
        ((AnnotationConfigApplicationContext)ctx).close();
    }
}

 

 

 

3.Spring Test


Spring's test framework is based on JUnit test framework, which is a re encapsulation of JUnit.

Use:

Plug in configuration file pom.xml

<!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12-beta-3</version>
            <scope>test</scope>
        </dependency>
        <!-- Spring Test -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.7.RELEASE</version>
            <scope>test</scope>
        </dependency>

 

Code for the sample test project:

/**
 * Service interface
 * @author Zhang Ze
 *
 */

public interface IUserService {
    void login();
}

 

 

import org.springframework.stereotype.Component;

/**
 * Business implementation class
 * @author Zhang Ze
 *
 */
@Component
public class UserServiceImpl implements IUserService {

    @Override
    public void login() {
        System.out.println("login success");
        
    }

}

 

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * Spring To configure
 * @author Zhang Ze
 *
 */
@Configuration
@ComponentScan("day03")
public class AppConfig {
    
    @Bean("hello")
    public String hello() {
        return "hello";
    }
}

 

 

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * call
 * @author Zhang Ze
 *
 */
public class Invoker {
    public static void main(String[] args) {
        //-- Spring COntainer
        ApplicationContext ctx = 
                new AnnotationConfigApplicationContext(AppConfig.class);
        //-- 2.
        System.out.println(ctx.getBean("hello"));
    }
}

 

 

JUnit test code:

/**
 * 1. Unit test with JUnit
 * @author Zhang Ze
 *
 */

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestDemo {
    private ApplicationContext ctx;
    
    @Before
    public void before() {
        ctx = new AnnotationConfigApplicationContext(AppConfig.class);    
    }
    
    @Test
    public void test() {
        System.out.println(ctx.getBean("hello"));
    }
    
    
}

 

Use the Spring test framework to test:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * 2. Using Spring test framework
 * 
 * @RunWith: Instantiate Spring container
 * @ContextConfiguration: Specify the configuration class required by the Spring container
 * In the future, you will rarely see the Spring container
 * 
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= {AppConfig.class})
public class TestSpringDemo {
    @Autowired
    private String hi;
    @Autowired
    private IUserService userService;
    
    @Test
    public void test() {
        System.out.println(hi);
    }
    @Test
    public void test1() {
        userService.login();
    }
}

 

 

Configuration file for this project: pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.uek.course</groupId>
    <artifactId>spring-app</artifactId>
    <version>0.0.1</version>
    <packaging>war</packaging>

    <!-- 2. Project property configuration -->
    <properties>
        <!-- Use of project code UTF-8 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- Ignore web.xml File, because we use servlet3.0 Development web project -->
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <spring.version>5.1.7.RELEASE</spring.version>
    </properties>
    <!-- 3. Third party required for configuration project jar package -->
    <dependencies>
        <!-- servlet api -->
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- MySQL Database connection pool -->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!-- Druid -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.20</version>
        </dependency>
        <!-- unit testing -->
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12-beta-3</version>
            <scope>test</scope>
        </dependency>
        <!-- Spring Test -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
        
        
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.10</version>
        </dependency>
        
        
        <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
                
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
    
    
    </dependencies>



    <!-- Configure build plug-ins -->
    <build>
        <plugins>
            <plugin>
                <!-- Compiler plug-in -->
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!-- Tomcat Plug-in unit -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <path>/airsys</path>
                    <!-- Implement hot deployment without restarting every time the code is modified Tomcat -->
                    <contextReloadable>true</contextReloadable>
                </configuration>
            </plugin>


        </plugins>
    </build>
</project>

Posted by Square1 on Wed, 30 Oct 2019 12:56:27 -0700