1.Spring IOC

  IOC技术: 控制反转,也叫(依赖注入)

  控制反转:Bean的生命周期不受你控制,而是交给Spring容器管理。

  Spring框架如何利用IOC ?:
          实现了控制反转,Spring容器能帮我们实例化对象,但是并没有做到DI(依赖注入)。

  作用:
        (1) 构建Bean
        (2) Bean之间有依赖关系的话,可以自动帮我们注入
    优势:
        解耦:低耦合,实现面向接口的编程思想

2.Spring AOP

  动态代理设计模式
      原理和静态代理设计模式没有本质区别:
          被代理类、代理类、被代理和代理类是同一个接口
          代理类的创建过程有区别:
          (1)静态代理:
                  自己编写代理类,代理类自己实现接口
          (2)动态代理:
                  代理类不需要自己编写,他Proxy.newProxyinstance(xx)静态方法
                  在程序执行过程中,动态产生代理类
                  InvocationHandler:里边含有被代理类的引用

   AOP:面向切面的编程

  代理模式主要的作用:
          在业务代码不之情的情况下,切入额外的功能。
    原理:Spring框架具有IOC的功能,所以我们可以利用该功能配置业务Bean 。代理设计模式(动态)
        例如: AccountServiceImpl
        <bean id="AccountServiceImpl" class="service.AccountServiceImpl"></bean>
        然后,Spring框架利用动态代理设计模式创建一个AccountServiceImpl的动态代理对象
        然后就可以在AccountServiceImpl的业务方法的基础上增加相应的功能。
        那Spring把这种技术称为AOP面向切面的编程,其实就是在程序员不知情的情况下在其业务方法上切入额外的功能。

  使用 XML 配置实现具体的操作:
      (1)使用Spring的AOP功能,就需要引入jar  pom.xml
      (2)自己编写切面。很类似于InvocationHandler
          被代理接口   :  业务接口
          被代理类: 实现了被代理口,被代理类也叫业务实现类;
          例子:class CalFfabImpl implements ICalFab

代码示例:

  Maven项目

  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>

  添加资源配置文件 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 配置切面 -->
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="selfAspectRef">
<!-- 切点 在CalFabImpl类的任何方法上加通知 -->
<aop:pointcut expression="execution(* day02.aop.CalFabImpl.*(..))" id="selfPointcut"/>
<!-- 通知 -->
<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>

  新建接口 ICalFab.java

 /**
* 业务接口
* @author 张泽
*/
public interface ICalFab { int calFaByLoop(int n);
int calFabByRecursion(int n); }

  新建类实现接口:

/**
* 业务实现类:被代理类
* @author 张泽
*/
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); } }

  新建类:SelfAspect.java

import org.aspectj.lang.ProceedingJoinPoint;

/**
* 自定义功能性切面:利用xml配置实现。
* @author 张泽
*
*/
public class SelfAspect {
//--通知:Before类型的Advice
public void testBefore() {
System.out.println("before do something...");
}
//--通知:after类型的通知
public void testAfter() {
System.out.println("after do Something...");
}
//-- 通知:Around环绕 通知方法的执行点
public int testAround(ProceedingJoinPoint jp) {
int result = 0;
try {
long start = System.currentTimeMillis();
result = (int)jp.proceed(); //-- 执行业务方法
long end = System.currentTimeMillis();
System.out.println(end-start+"ms");
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
}

  新建调用类:Invoker.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* Invoker类
* 功能切入更加灵活
* @author 张泽
*
*/
public class Invoker {
public static void main(String[] args) {
//-- 1. Spring容器
ApplicationContext ctx =
new ClassPathXmlApplicationContext("application.xml");
//-- 2. 获取业务类
ICalFab calFab= (ICalFab)ctx.getBean("calFab");
//-- 3. 调用业务方法
System.out.println(calFab.calFaByLoop(40));
System.out.println(calFab.calFabByRecursion(40));
System.out.println(calFab instanceof ICalFab); }
}

  使用 注解 配置实现具体的操作:

    (1) Config类来代替xml的配置
          @EnableAspectJAutoProxy //-- 启用SpringAop的功能
          //-- 启用Spring的IOC功能
          @Configuration
          @ComponentScan({"package1","package2"})
      (2)编写切面。

代码示例:

  新建接口 ICalFab.java

/**
* 业务接口
* @author 张泽
*
*/ public interface ICalFab { int calFaByLoop(int n);
int calFabByRecursion(int n); }

  新建实现类 CalFabImpl.java

import org.springframework.stereotype.Component;

/**
* 业务实现类:被代理类
* @author 张泽
*/
@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); } }

  新建配置类 AppConfig.java

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; /**
* 配置类
* @author 张泽
* 实现IOC功能
*
*/
@Configuration
@EnableAspectJAutoProxy //-- 启用SpringAop的功能
@ComponentScan("day.annocation")//-- 包名
public class AppConfig {
// @Bean
// public ICalFab calFabBean() {
// return new CalFabImpl();
// }
}

  新建类: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; /**
* 利用标注自定义切面
* @author 张泽
*
*/
@Aspect
@Component
public class SelfAspect { //-- 1. 自定义切点,指定目标方法的位置
@Pointcut("execution(* day02.annocation.CalFabImpl.*(..))")
public void selfPointcut() { }
//-- 2. 通知
@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(); //-- 执行业务方法
long end = System.currentTimeMillis();
System.out.println(end-start+"ms");
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
}

  新建类:Invoker.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Invoker {
public static void main(String[] args) {
//-- 1.构造Spring容器
ApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
//-- 2.获取Beans
ICalFab calFab =(ICalFab)ctx.getBean("calFabImpl");//-- 默认是类名首字母小写
calFab.calFabByRecursion(40); //-- Web服务器启动的时候实例化一个Spring容器,在Web服务器关闭的时候关闭Spring容器
//-- Servlet的监听
//-- 容器关闭
((AnnotationConfigApplicationContext)ctx).close();
}
}

3.Spring Test

 Spring 的测试框架建立在JUnit测试框架基础上的,它是对JUnit的再次封装。

使用:

  配置文件 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>

示例测试工程的代码:

/**
* 业务接口
* @author 张泽
*
*/ public interface IUserService {
void login();
}
import org.springframework.stereotype.Component;

/**
* 业务实现类
* @author 张泽
*
*/
@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配置
* @author 张泽
*
*/
@Configuration
@ComponentScan("day03")
public class AppConfig { @Bean("hello")
public String hello() {
return "hello";
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; /**
* 调用
* @author 张泽
*
*/
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测试代码:

/**
* 1. 先利用JUnit做单元测试
* @author 张泽
*
*/ 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"));
} }
利用Spring 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. 利用Spring test 框架
*
* @RunWith: 实例化Spring容器
* @ContextConfiguration: 指定Spring容器需要的配置类
* 以后你会很少看到Spring容器了
*
*/
@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();
}
}

该项目的配置文件: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. 项目属性配置 -->
<properties>
<!-- 项目编码使用UTF-8 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 忽略掉web.xml文件 ,因为我们使用servlet3.0开发web项目 -->
<failOnMissingWebXml>false</failOnMissingWebXml>
<spring.version>5.1.7.RELEASE</spring.version>
</properties>
<!-- 3. 配置项目所需要的第三方jar 包 -->
<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数据库连接池 -->
<!-- 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>
<!-- 单元测试 -->
<!-- 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> <!-- 配置构建插件 -->
<build>
<plugins>
<plugin>
<!-- 编译插件 -->
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- Tomcat 插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/airsys</path>
<!-- 实现热部署,不需要每次修改代码后都重新启动Tomcat -->
<contextReloadable>true</contextReloadable>
</configuration>
</plugin> </plugins>
</build>
</project>

Spring框架 --- 深入的更多相关文章

  1. Spring框架概述

    Spring是最流行的Java企业级应用开发框架,全球数以百万的开发者在使用Spring框架创建高性能.易测试.可重用的代码. Spring框架的核心特性可以应用于任何Java应用,但扩展的JavaE ...

  2. 初识Spring框架实现IOC和DI(依赖注入)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的, IoC是 ...

  3. Spring 框架的架包分析、功能作用、优点,及jar架包简介

    Spring 框架的架包详解    Spring的作用     Spring的优势  由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或 ...

  4. 最新 Eclipse IDE下的Spring框架配置及简单实例

    前段时间开始着手学习Spring框架,又是买书又是看视频找教程的,可是鲜有介绍如何配置Spring+Eclipse的方法,现在将我的成功经验分享给大家. 本文的一些源代码来源于码农教程:http:// ...

  5. spring框架学习(三)

    一.Spring自动组件扫描 Spring 提供组件扫描(component scanning)功能.它能从指定的classpath里自动扫描.侦测和实例化具有特定注解的组件. 基本的注解是@Comp ...

  6. Spring框架学习(一)

    一. spring概述 Spring 框架是一个分层架构,由 7 个定义良好的模块组成.Spring 模块构建在核心容器之上,核心容器定义了创建.配置和管理 bean 的方式,如图 1 所示. 图 1 ...

  7. Spring 系列: Spring 框架简介 -7个部分

    Spring 系列: Spring 框架简介 Spring AOP 和 IOC 容器入门 在这由三部分组成的介绍 Spring 框架的系列文章的第一期中,将开始学习如何用 Spring 技术构建轻量级 ...

  8. 使用 Spring Boot 快速构建 Spring 框架应用--转

    原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/ Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2 ...

  9. 【Spring】浅析Spring框架的搭建

    c目录结构: // contents structure [-] Spring是什么 搭建Spring框架 简单Demo 1,建立User类 2,建立Test类 3,建立ApplicationCont ...

  10. Spring框架总结

    Spring(由Rod Johnson创建的一个开源框架) Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建.简单来说,Spr ...

随机推荐

  1. The type java.lang.AutoCloseable cannot be resolved. It is indirectly referenced from required .class files

    出现问题: The type java.lang.AutoCloseable cannot be resolved. It is indirectly referenced from required ...

  2. Mysql的表级锁和行级锁

    表级锁 MySQL表级锁分为读锁和写锁. 读锁 用法:LOCK TABLE table_name [ AS alias_name ] READ 释放锁使用UNLOCK tables.可以为表使用别名, ...

  3. vue 引入 fontawesome 报错 Could not find one or more icon(s) 解决

    在 vue 项目中引用 fontawesome , 按照官方说明如下步骤操作 1. 终端中执行 $ npm i --save @fortawesome/fontawesome-svg-core $ n ...

  4. 队列 & 栈---概述

    队列 是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作 ...

  5. Spring Boot WebFlux 快速入门实践

    02:WebFlux 快速入门实践 Spring Boot 2.0 spring.io 官网有句醒目的话是: BUILD ANYTHING WITH SPRING BOOT Spring Boot ( ...

  6. 基于STM32F429和HAL库的CAN收发例程

    1.CAN协议介绍 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议.在当前的汽车产业中,出于对安全性.舒适性.方便性.低公 ...

  7. Mac安装Command Line Tools

    从App Store上下载的Xcode,默认是不会安装Command Line Tools的,Command Line Tools是在Xcode中的一款工具,可以在命令行中运行C程序. 在终端中输入命 ...

  8. GUI tkinter (Entry) 输入框篇

    """1.其他函数不常用,这里只说get函数,get函数使用的时候不需要任何参数,它的返回值就是该输入框的内容.""" from tkint ...

  9. 从零起步 系统入门Python爬虫工程师 ✌✌

    从零起步 系统入门Python爬虫工程师 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 大数据时代,python爬虫工程师人才猛增,本课程专为爬虫工程师打造, ...

  10. unittest生成测试报告

    1.先导入HTMLTestRunner模块 2.实例一脚本如下 #coding=utf-8 import unittest import HTMLTestRunner #封装批量执行用例 def al ...