一、Spring介绍

Spring 是位于业务逻辑层的框架。 优点很多(无缝对接前后层的框架、提供AOP的支持 , 和以前的 Sstruts 、 Hibernate 组合成了一套框架组合 SSH 。现在是和Spring MVC 、 MyBatis 成了新的组合 SSM) 。 spring里面包含两个核心 : IOC + AOP

  • IOC

IOC 的全称是 Inversion Of Control 翻译过来是控制反转的意思。 通俗的说: 就是把对象的创建工作交给spring来完成。

	以前创建对象 :  new 类(); ----> 把工作交给spring ----> 问spring要对象即可
  • AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程

二、IOC演变

创建对象的发展历史

  • 早期直接new对象

  • 演变成工厂

  • spring ioc托管

三、Spring入门

1. 入门案例

  1. 添加依赖
 compile 'org.springframework:spring-context:4.3.17.RELEASE'
  1. 编写业务逻辑类
public interface UserService {
void save();
} public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("调用UserServiceImpl的save方法~~");
}
}
  1. 创建配置文件 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/> </beans>
  1. 在代码里面通过工厂获取对象
public class MainTest {
@Test
public void testSave(){
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) context.getBean("userService");
userService.save();
context.close();
}
}

2. 配置详解

1. xml解释

 <!-- bean标签用来托管具体类,也就是告诉spring工厂,我们让它帮忙创建谁的实例对象 

    	id | name: 唯一标识符,不建议写一样的内容
class : 全路径 默认创建的实例是单例.
如果想要做成多例,那么请使用scope属性,里面给值prototype ,
默认是单例 ==== singleton
--> <bean id="us" class="com.itheima.service.impl.UserServiceImpl" scope="prototype"></bean>

2. 代码解释

//2. 让spring创建对象 问spring的工厂要对象
//创建工厂,然后告诉工厂,配置文件在哪里。 工厂就会解析这个xml文件,进而得出us --- UserServiceImpl的对应关系
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //问工厂要对象
UserService userService =(UserService) context.getBean("us"); userService.save(); //关闭工厂,一般不会调用这个方法。
((AbstractApplicationContext) context).close();

四、IOC

此处使用两种方式给大家介绍, xml注解方式

1. xml方式

  • 代码:
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("调用UserServiceImpl的save方法~~");
}
}
  • xml配置
 <bean id="us" class="com.itheima.service.impl.UserServiceImpl"></bean>

2. 注解方式

即便使用注解,也还是需要在配置文件里面声明注解的开关

  • 代码
@Compoment
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("调用UserServiceImpl的save方法~~");
}
}
  • xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
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"> <!-- 打开扫描开关 -->
<context:component-scan base-package="com.itheima"/>
</beans>
  • 细节
  1. 为了迎合三层结构的趋势,Spring 为每一个层级制定了各自的注解,

​ controller层使用 @Controller

​ service层使用@Service

​ dao层使用@Repository

  1. 如果需要给指定的bean添加标识,可以使用注解属性追加 如: @service("userService")

  2. 默认情况下生成的实例还是单例,如果需要做成多例,需要额外加上 @Scope("prototype")

五、依赖注入

DI : 全称是 dependency Injection 翻译过来是依赖注入 本意是在实例化对象的时候,对它里面的成员属性进行值的注入。

public class UserServiceImpl{

​ private String address;

}

对这个address进行赋值: 有几种方式: 两种

  1. 有参构造

  2. set方法

    依赖注入,走的就是上面的这两种。 如果使用注解注入,使用的是反射。

1. xml方式

xml方式需要在配置文件中配置,以完成值的注入,提供两种方法, 有参构造和set方法。

a. 有参构造

  • 代码
public class UserServiceImpl implements UserService {

	private String address;

	//必须走有参构造
public UserServiceImpl(String address) {
this.address = address;
} @Override
public void save() {
System.out.println("调用UserServiceImpl的save方法~~" + address);
}
}
  • xml配置
<bean id="us" class="com.itheima.service.impl.UserServiceImpl" >
<!--
constructor-arg : 一旦配置,就指定了spring的工厂走的是 有参构造。
name:说的是属性名称
value: 注入的值 -->
<constructor-arg name="address" value="深圳"></constructor-arg>
</bean>

b. set方法

  • 代码
public class UserServiceImpl implements UserService {

	private String address;

	public void setAddress(String address) {
this.address = address;
} @Override
public void save() {
System.out.println("调用UserServiceImpl的save方法~~" + address);
}
}
  • xml配置
<bean id="us" class="com.itheima.service.impl.UserServiceImpl" >

  <!-- 	property标签对应的是代码里面set方法
name: 属性的名称
value: 要注入的值 -->
<property name="address" value="深圳"></property>
</bean>

c. 注入集合类型

1. 数组

代码:

	private String [] address;

	public void setAddress(String [] address) {
this.address = address;
} xml: <property name="address">
<array>
<value>北京1</value>
<value>北京2</value>
<value>北京3</value>
<value>北京天安门,我爱北京</value>
</array>
</property>

2. list

代码:

	private List  address;

	public void setAddress(List  address) {
this.address = address;
} xml: <property name="address">
<list>
<value>北京11</value>
<value>北京22</value>
<value>北京33</value>
<value>北京天安门,我爱北京44</value>
</list>
</property>

3. map

代码:

	private Map<String , Object>  address;

	public void setAddress(Map<String , Object>  address) {
this.address = address;
} xml: <!-- map集合 -->
<property name="address">
<map>
<entry key="地址1" value="北京1"/>
<entry key="地址2" value="北京2"/>
<entry key="地址3" value="北京3"/>
<entry key="地址4" value="北京4"/>
</map>
</property>

d. 注入 对象类型

在某一个类当中,持有另一个类的引用,我们需要让spring创建这个类的引用,进而通过调用set方法来完成注入

  • 代码
public class UserServiceImpl implements UserService {

		private UserDao userDao;// = new UserDaoImpl(); 体现了两层意思: a. new 某一个类的实例, b. 做出来的实例,赋值给dao.

		public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} @Override
public void save() {
System.out.println("调用UserServiceImpl的save方法~~" );
//UserDao userDao = new UserDaoImpl();
userDao.save();
}
}
  • xml
<!-- 让spring托管这个UserDaoImpl ,以便它能够创建该类的实例, 是为了完成下面的注入 -->
<bean id="ud" class="com.itheima.dao.impl.UserDaoImpl"></bean> <bean id="us" class="com.itheima.service.impl.UserServiceImpl" > <!-- 指定了UserServiceImpl里面有一个属性叫做userDao ,它需要被注入, 注入的数据来自于 ref 里面声明的ud
spring会拿着ud 找到对应的bean, 接着做出来实例,然后注入给userDao -->
<property name="userDao" ref="ud"></property>
</bean>

2. 注解方式

依赖注入使用注解来实现 , DI的注解一般使用两个 @Resource & @Autowired

  • 常用的注解就两个 @Resource & @Autowired

@Resource(name="ud") 根据给定的标记找到对应的类,创建对象,注入进来。

@Autowired 自动装配,会找到对应的实现类创建对象,注入进来。但是如果存在多个实现,那么会抛出异常

@Repository("ud")
public class UserDaoImpl implements UserDao {
} public class UserServiceImpl implements UserService { @Resource(name="ud") //spring拿着ud找到具体的类,然后创建实例,注入进来。
private UserDao userDao; ...
} ---------------------------------------------------------- public class UserServiceImpl implements UserService { @Autowired //自动装配 根据注入的接口类型找到对应的实现类,注入进来。
private UserDao userDao; ...
}

三、 AOP

1. 什么是AOP ? 它有什么用?

AOP(Aspect Oriented Programming,面向切面编程), 可以说是OOP(Object Oriented Programing,面向对象编程)的补充和完善。在不改动源码的前提下,对原有的功能进行扩展 | 升级

2. AOP的底层原理

在java的世界里,能够不改动源码,但是又能做出扩展|增强的,不多。有装饰者模式, 有代理模式(静态代理 + 动态代理。) aop的底层采用的是: 动态代理。之所以不用装饰者模式或者静态代理,那是因为这里两种方式,都需要我们写实实在在的扩展类(装饰类 + 代理类) 。

  • 代理回顾

3. 动态代理的实现方式

  • 基于JDK的方式

针对的是被代理类有实现某一个接口,底层创建接口的另一个实现类作为代理类

//jdk动态代理
@Test
public void testJDKPorxy(){ //UserService userService = new UserServiceImpl();
//userService.save(); //1. 先创建真实对象
final UserService userService = new UserServiceImpl(); //2. 创建代理对象
UserService proxyObj = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(), //类加载器,真实类用什么,代理类就用什么
userService.getClass().getInterfaces(), //真实类实现什么接口,代理类也实现什么接口
new InvocationHandler() {//回调函数 @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke~");
//userService.save(); if(method.getName().equals("save")){
Logger.log();
} //以不变应万变。 反射调用
return method.invoke(userService, args);
}
}); //3. 让代理对象干活
proxyObj.save(); //代理对象。save() ----> 真实对象.save();
}
  • 基于Cglib动态代理

如果真实类是一个普通类,没有实现接口,那么就采用这种方式, 创建出来真实类的子类作为代理类。

//cglib动态代理
@Test
public void testCglibPorxy(){
//1. 一定要有真实对象
final ProductService productService = new ProductService();
//2. 创建代理
Enhancer enhancer = new Enhancer();
//设置父类是谁
enhancer.setSuperclass(ProductService.class);
//设置回调
enhancer.setCallback(new MethodInterceptor() { /*
* arg0 :代理对象
* arg3 : 方法的代理
*
* 一般这两不用。
*
* arg1 : 方法引用
* arg2 :参数
*/
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
Logger.log();
return arg1.invoke(productService, arg2);
}
}); //创建代理对象
ProductService proxyObj = (ProductService) enhancer.create();
proxyObj.save(); }

3. AOP术语

4.AOP的入门

Spring的AOP其实已经准备好了创建代理的代码。只是不知道的是要创建谁的代码。哪些方法需要被增强。我们需要通过配置的形式告诉spring。

  1. 定义业务逻辑类
public class UserServiceImpl implements UserService {

	@Override
public void save() {
System.out.println("调用了UserServiceImpl 的 save方法");
}
}
  1. 定义增强类
public class Logger {
public static void log(){
System.out.println("输出日志了~~");
}
}
  1. 添加依赖
    compile 'org.springframework:spring-context:4.3.17.RELEASE'

	//aspectJ 依赖包。
compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.10'
  1. xml中配置

要导入aop的约束

让spring托管 业务逻辑类 和 增强类
<bean id="us" class="com.itheima.service.impl.UserServiceImpl" ></bean>
<bean id="logger" class="com.itheima.util.Logger" ></bean> 配置AOP <!-- 2. 开始配置aop -->
<aop:config> <!-- 配置切入点 expression 表达式 '
execution(* com.xyz.myapp.service.*.*(..)) execution 固定写法
第一个* 代表任意返回值
com.xyz.myapp.service : 包名
第二个* 包下的任意类
第三个* 类中的任意方法
(..) : 任意参数 saveUser
saveOrder
-->
<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="aa"/> <!-- 配置增强 根据aa的表达式找到的方法,都给他们做前置增强,增强的功能是log方法
-->
<aop:aspect ref="logger">
<aop:before method="log" pointcut-ref="aa"/>
</aop:aspect>
</aop:config>

5. AOP 增强

  <aop:config>

   <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pointcut01"/>

 	<!-- 以后去企业写代码,真正用aop来扩展一个功能,比较少。 除非是我们想扩展第三方jar包。
aop的思想无处不在: struts 拦截器 (就是AOP) --> <!-- 配置切面aspect -->
<aop:aspect ref="logger">
<!-- 前置增强 -->
<!-- <aop:before method="log" pointcut-ref="pointcut01"/> --> <!-- 最终增强 -->
<!-- <aop:after method="log" pointcut-ref="pointcut01"/> --> <!-- 后置增强 -->
<!-- <aop:after-returning method="log" pointcut-ref="pointcut01"/> --> <!-- 异常增强 -->
<!-- <aop:after-throwing method="log" pointcut-ref="pointcut01"/> --> <!-- 环绕增强 -->
<!-- <aop:around method="around" pointcut-ref="pointcut01"/> --> <aop:before method="log" pointcut-ref="pointcut01"/>
<aop:after-returning method="log" pointcut-ref="pointcut01"/> </aop:aspect> </aop:config>

springboot10 framwork的更多相关文章

  1. 1.使用Entity Framwork框架常用的技术手段Code First 和Reverse Engineer Code First

    提示:VS版本2013,  Entity Framwork版本5.0.0,Mysql数据库  使用Entity FrameWork的好处就不多说,直接上手如何使用.两种形式:1.将代码映射到数据库实体 ...

  2. [读书笔记]C#学习笔记一: .Net Framwork

    前言: 一次偶然的机会  在园子里看到@Learning hard 出版的一本书: <<C#学习笔记>>, 然后买来 一直到现在读完, 感觉很不错, 适合入门, 书中内容是从C ...

  3. C#笔记一 .Net Framwork

    参考Learning hard本人在博客园的主页: http://www.cnblogs.com/zhili/     以及本书中的一些知识点: http://www.cnblogs.com/zhil ...

  4. 018如何建立自动化框架 how to bulid the framwork

    本讲包括: 一. objective 二. How to bulid 三. Keyview of frawork (关键视图) 四. conclusion automation framwork:自动 ...

  5. Entity Framwork db First 中 Model验证解决办法。

    由于项目中用到 Entity Framwork db First     每次从数据库生成数据模型之后都会把模型更新. 只要有一个表更新.所有的类都会重新生成. 在网上找了各种例子都是差不多的, 可能 ...

  6. 温故而知新之java的collection framwork

    经常用到的List,Map等这些数据结构,都是来自于java的util包下,而java对于其整体设计,简称为collection framwork.(ps.其实,Map接口并不继承自collectio ...

  7. rabbitmq支持.net framwork 3.5的最后版本

    方便后来人!!!经过一系列的确认!! rabbitmq支持.net framwork 3.5的最后版本是3.4.3, 安装步骤: 1.工具->Nuget程序包管理器,进入控制台 2.Instal ...

  8. REST framwork之分页器,路由器,响应器

    一 REST framwork分页器: from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination ...

  9. 记录一次BUG修复-Entity Framwork SaveChanges()失效

    目录 一. 前言 二.问题背景 三.问题描述 四.问题解决步骤 六.总结 一. 前言 这是笔者在参与一个小型项目开发时所遇到的一个BUG,因为项目经验不足对Entity Framwork框架认识不足导 ...

随机推荐

  1. 第51章 设置FLASH的读写保护及解除—零死角玩转STM32-F429系列

    第51章     设置FLASH的读写保护及解除 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  2. 【Java】数组知识回顾

    package another; import java.util.Arrays; import java.util.List; /** * 数组知识回顾 * @author ChristineBas ...

  3. docker简介以及优缺点

    1.docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制, ...

  4. js常用的2中排序方法:冒泡排序和快速排序

    冒泡排序:例如9 4 5 6 8 3 2 7 10 1 首先:9和4比较  4放前   4 9 5 6 8 3 2 7 10 1 4和5比较   4不动   4 9 5 6 8 3 2 7 10 1 ...

  5. MyBatis---自动创建表

    该项目基于Maven实现 该项目实现了在项目启动时,对数据库表进行操作 源码下载 实现步骤: 1.向pom.xml文件添加maven依赖 <dependency> <groupId& ...

  6. Struts2---数据封装机制

    Struts2属性驱动和模型驱动 自动完成了数据的获取和封装 LoginAction.java public class LoginAction implements ModelDriven<U ...

  7. 编译ffmpeg

    1.下载ffmpeg-0.9.2.tar.gz  http://ffmpeg.org/releases/ 下载需要的版本 2.编译linux (centos5.5) 64位版本 ./configure ...

  8. oracle 用户被锁定解锁方法

    修改了用户密码,第二天过来发现用户被锁定,晚上走的时候还好好的 . alter profile DEFAULT limit FAILED_LOGIN_ATTEMPTS UNLIMITED; alter ...

  9. 站在C#和JS的角度细谈函数式编程与闭包

    1.函数式编程是什么? 摘自百度的说法是.函数式编程是种编程典范,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 λ 演算(lambda calculus).而且λ演算的函数可以接受函数当作输 ...

  10. __bridge 使用注意

    前奏 在平常开发中,我们可能遇到 CoreFoundation(CF) 框架的对象和 OC 对象之间的类型转换,这时候我们需要 __bridge 来帮忙 注意 : 如果是使用 CF __bridge ...