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>