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. 容器时代的持续交付工具---Drone:Drone介绍与安装

    Drone:Drone is a Container-Native, Continuous Delivery Platform. 官方给的定义,从上面的定义可以得出两个关键点: 1,Container ...

  2. Java线程池基础

    目录: 一.线程池概述 二.线程池参数 三.线程池的执行过程 四.线程池的主要实现 五.线程池的使用 六.线程池的正确关闭方式 七.线程池参数调优 一.线程池概述 1.线程池类 目前线程池类一般有两个 ...

  3. 第六届蓝桥杯java b组第五题

    九数组分数 1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. public class A { public static vo ...

  4. IDEA加密算法(含所需jar包(commons-codec-1.11.jar ,bcprov-jdk15on-160.jar))

    软件设计上机实验IDEA算法: import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Se ...

  5. JMeter 压测Server Agent无法监控资源问题,PerfMon Metrics Collector报Waiting for sample,Error loading results file - see file log, Can't accept UDP connections java.net.BindException: Address already in use 各种疑难杂症

    如何安装插件此博主已经说得很详细了. https://www.cnblogs.com/saryli/p/6596647.html 但是需注意几点: 1.修改默认端口,这样可以避免掉一个问题.Serve ...

  6. wpf 使用矢量字体 fontawesome

    第一步:首先下载矢量字体 :http://www.fontawesome.com.cn/ 第二步:在将fontawesome-webfont.ttf 文件引用到项目 设置fontawesome-web ...

  7. springboot系列之02-需要了解的宏观知识点

    未经允许,不得转载 原作者:字母哥博客 本文完整系列出自:springboot深入浅出系列 一.Spring Boot . Spring MVC .Spring对比 首先你需要明白一件事情:Sprin ...

  8. Idea 设置Eclipse快捷键(常用)

    使用Idea不习惯,特此将其配置成Eclipse风格的. 1.选择Eclipse风格,选择copy一份,可以自己重命名. 2.设置生成快捷键的快捷键(例如:Eclipse中的Alt+/) 3.设置ma ...

  9. 百万it资源百度网盘链接分享

    自己大量时间整理的优质资源,容量达3000多G,有需要的朋友可以微我,资源截图:  面试资料: 书籍类: 视频类: 以上只是部分资源,想要资源的亲请加微信咨询. 欢迎加微信咨询,请备注资源: 独乐乐不 ...

  10. <q> 与 <blockquote> 的区别

    <q> 标签在本质上与 <blockquote> 是一样的.不同之处在于它们的显示和应用.<q> 标签用于简短的行内引用.如果需要从周围内容分离出来比较长的部分(通 ...