1.Spring简介一句话概括Spring,Spring是一个开源的、轻量的管制反转(IOC)和面向切面编程(AOP)的框架。1.1Spring、SpringMVC、SpringB
文章目录[隐藏] - 1. Spring简介
- 2. 管制反转—IOC
- 3. 面向切面编程—AOP
- 4. 参考资料
1. Spring简介
一句话概括Spring,Spring是一个开源的、轻量的管制反转(IOC)和面向切面编程(AOP)的框架。
1.1 Spring、SpringMVC、Spring Boot和Spring Cloud的区别
SpringMVC是在Spring根底之上联合了MVC三层架构的框架,应用DispatchServlet和视图解析器做到了更不便的视图跳转和控制器调度解决,次要负责解决WEB利用开发。SpringMVC是Spring的一个子模块。
SpringBoot则应用了约定大于配置的理念,简化了Spring配置,专一于微服务的开发。
SpringCloud专一于全局微服务的整合、治理。
2. 管制反转—IOC
2.1 基本概念
IOC:管制反转,是一种设计思维。即将对象创立的控制权转移给了Spring容器。
假如咱们创立了类A,类A中有个成员变量类B。
- 传统开发:咱们须要手动创立类B的对象,将他赋给类A的对象,这叫被动管制对象的创立;
- IOC:Spring创立好B对象,而后存储到一个容器外面,当A对象须要应用B对象时,Spring就从寄存对象的那个容器外面取出A要应用的那个B对象。
应用传统形式,A对B产生了依赖,也就是A和B之间存在一种耦合关系(假如B的实现有了改变,咱们可能还须要改变A的源码),而通过IOC的思维,这种依赖关系就被容器取代了,所有对象的创立依赖于容器,在启动的时候,Spring会读取配置文件,并将创立的对象先注入容器,之后咱们想要应用间接从容器中取就能够。
DI:依赖注入,能够了解为是Spring实现IOC的具体形式。
2.2 Spring创建对象形式
class UserService {
private UserDao dao;
public void setUserDao(UserDao dao) {
this.userDao = dao;
}
}
class UserDao {
private String name;
public void setName(String name) {
this.name = name;
}
}
2.2.1 构造函数
注:
- 如果某类有无参构造方法,则默认调用无参构造方法;
- 如果某类只有一个构造方法,则默认调用该构造方法。
2.2.2 property(调用set办法创立)
注:
- 应用属性注入时,容器会默认调用无参构造方法创立实例,所以须要保障要创立的bean有无参的构造方法;
- 应用属性注入等价于调用了
setXXX
办法,XXX是property标签中的name,假如下面的代码的setName
办法改成了setName1
,则第一个bean的property需这样写:
2.3 Bean的主动拆卸(autowiring)
主动拆卸即Spring在上下文中主动寻找,主动给bean拆卸属性。
bean的主动拆卸次要有三种策略:
byname
:把与某bean(A)属性具备雷同名字的其余bean(B)主动拆卸到该bean(A)的属性中;
byType
:把与某bean(A)属性具备雷同类型的其余bean(B)主动拆卸到该bean(A)的属性中;
constructor
:把与某bean(A)的结构器入参具备雷同类型的其余bean(B)主动拆卸到该bean(A)的属性中;
2.3.1 byName
xml配置形式
2.3.2 byType
xml配置形式
2.4 Spring注解配置
JDK1.5开始反对注解,而Spring是2.5开始反对。
应用Spring注解配置须要先导入束缚: context名称空间和注解扫描。
@Autowired
之后在须要主动拆卸的属性或set办法上应用@AutoWired注解,就能够实现主动拆卸。
//具体的可润饰范畴
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
注:@Autowired会先应用byType,再按byName的程序主动拆卸。
@Autowired有一个罕用属性:required,默认值为true,这个属性示意润饰的成员变量是否肯定须要拆卸一个bean:
- 当required设置为true时,示意必须有一个能够主动拆卸到该成员变量的bean,否则报错;
- 当required设置为false时,则示意该成员变量能够为null;
@Qualifier
当有多个bean满足主动拆卸条件时,能够应用这个指定拆卸的bean,个别配合@Autowired应用。
@Qualifier有个属性value,给这个value设置想要拆卸的bean的id即可。
@Component
润饰类,示意将该类的bean对象注入到Spring容器中。
@Component有个属性value,示意注入时设置的id。
如:
//等价于
@Component(value="user")
public class User {}
@Component有一些衍生注解,如Web开发会依照MVC架构分层,依据不同的性能层,衍生出了一些注解:
- @Repository:针对dao层
- @Service:针对service层
- @Controller:针对controller层
这四个注解性能统一,都示意将某类的bean对象注入到Spring容器中。
@Value
给属性注入值,次要用于给成员变量注入值,简略的能够注入根本类型的值,简单时能够注入一些操作系统属性或其余bean的属性。
@Scope
用于设置bean的作用域,先介绍最常见的:
- singleton:全局惟一,单例;
- prototype:每次注入创立一个新的对象。
注解和配置的区别
xml性能更加弱小,方便管理保护。注解实用于简略的属性注入。
2.5 JavaConfig配置
Spring 3.0
之后开始反对了一种更优的配置形式:基于Java类的配置形式。通过减少@Configuration注解表明这是一个配置类,其底层为@Component(即该类的bean对象也会被Spring容器接管)。
@Configuration联合@Bean注解能够实现XML配置实现注入的性能,成果与
...
...
相似,在应用@Bean注解时,示意将该办法返回的对象加载进Spring容器,在应用@Bean润饰办法时须要留神:
- 办法带返回值,且返回类型为想要被治理的bean的类型;
- 办法名即为默认的bean name,可应用@Bean的name属性自定义;
- 办法可带参数,则此时传入的参数也必须是被Spring容器治理的bean。
以创立UserService和UserDao为例:
@Configuration
public class UserConfiguration {
@Bean
public UserService userService() {
return new UserService();
}
@Bean
public UserDao userDao() {
return new UserDao();
}
}
当Spring扫描该类时,会主动将UserConfiguration、UserService、UserDao的bean注入到Spring容器中进行托管。
3. 面向切面编程—AOP
3.1 基本概念
在软件开发中,咱们须要编写许多的业务代码,但还有很多代码是业务无关的,如
为了实现业务代码和非业务代码的拆散,Spring利用代理模式抽出了非业务代码,造成了AOP思维。
AOP全称Aspect Oriented Programming,意为面向切面编程,假如业务代码自身是一条纵向的逻辑流,咱们在其中找几个点(切点,Pointcut),插入非业务代码,就像是一个个切面(Aspect),这就是一个简略的AOP例子。
切面和切点很容易被混同,严格来说,切点是切面的一部分信息,切面次要蕴含两局部信息:
而在具体的实现中,Spring为切面还加了一个信息:在切点的哪个阶段执行?由此衍生出有:
- 前置告诉(Before):在指标办法被调用之前调用告诉性能;
- 后置告诉(After):在指标办法被调用之后调用告诉性能;
- 返回告诉(After-returning):在指标办法胜利执行之后调用告诉;
- 异样告诉(After-throwing):在指标办法抛出异样后调用告诉;
- 盘绕告诉(Around):告诉包裹了被告诉的办法,在被告诉的办法调用之前和调用之后执行自定义的行为。
对于AOP在Spring的实现有三种形式:
- 实现原生的Spring API接口
- 自定义切面类
- 注解
3.2 实现原生Spring API接口
Spring提供了诸如MethodBeforeAdvice、AfterAdvice、AfterReturningAdvice等原生接口,咱们能够通过实现这些接口构建切面,如
@Component
public class Log implements MethodBeforeAdvice {
/**
* @param method 要执行的指标对象办法
* @param objects 参数
* @param o 指标对象
* @throws Throwable
*/
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName() + "-" + method.getName() + "将要执行");
}
}
该Log类实现了MethodBeforeAdvice,成为了一个在办法执行前插入的切面,其次,咱们须要在XML中进行配置,设置切点并建设其和切面的连贯:
execution示意在办法执行时触发;*示意办法返回值能够是任意类型,com.dong.service.UserServiceImpl.*应用全限定类名和办法名指定要增加前置告诉的办法,应用*示意对com.dong.service.UserServiceImpl类下的所有办法都执行切入;(..)示意办法的参数列表,应用(..)示意办法的入参能够是任意类型。
须要留神,Log必须是一个被Spring容器治理的bean对象,否则Spring将无奈找到该切面的bean,因而应用@Component注解润饰(也能够应用XML配置等形式注入)。
3.3 自定义切面类
自定义切面不须要实现Spring的原生接口,首先须要定义一个切面类,并将加载给Spring容器进行托管。
@Component(value="diy")
public class DiyPointCut {
public void before() {
System.out.println("办法执行前");
}
public void after() {
System.out.println("办法执行后");
}
}
与3.2类似,该形式须要通过XML配置设置切点以及其和切面的连贯。
3.4 注解
3.4.1 启用注解性能
首先,应用注解有两种形式:
-
XML导入配置:
、
-
应用@EnableAspectJAutoProxy
注解须要被切的类
@Component(value = "userService")
@EnableAspectJAutoProxy
public class UserServiceImpl implements UserService {}
其次,应用注解时,须要留神两局部:
- 申明切面:申明某类是切面以及切入后理论要执行的动作(Advice);
- 定位切点:来源gaodai#ma#com搞@代~码网须要通过execution表达式定位须要切入的办法。
上面介绍一下注解的应用形式。
3.4.2 注解应用
只有对一个类应用@Aspect注解润饰,就表明这是一个切面。能够对其中的办法应用
- @Before
- @After
- @AfterReturning
- @Around
- @AfterThrowing
注解指定切入机会,切入点通过execution表达式指定,举例如下:
@Aspect
@Component
public class CustomPointCut {
@Before("execution(* com.dong.service.UserServiceImpl.*(..))")
public void before() {
System.out.println("aop:办法产生前");
}
}
4. 参考资料
- Spring最新5残缺教程
- Spring入门(十):Spring AOP应用解说
- Spring AOP – 注解形式应用介绍