Spring
- 需要导入的包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.26</version>
<scope>test</scope>
</dependency>
- spring配置文件
- 不使用注解注入时的头文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
-
- 使用注解注入时的头文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
</beans>
- IOC
控制反转(Inversion of Control,IoC)是一个比较抽象的概念,是Spring框架的核心,即业务类将对象的控制权移交给Spring容器。
依赖注入(Dependency Injection,DI)容器将业务需要的对象注入到业务所需的位置。
-
- BeanFactory接口
org.springframework.beans.factory.BeanFactory是IOC容器的核心接口,他的主要职责:实例化、定位、配置应用程序中的对象及建立这些对象之间的依赖
实例:
public class BeanFactoryTest {
public static void main(String[] args) {
//初始化Spring容器,加载配置文件
BeanFactory beanFac=
new XmlBeanFactory
(newFileSystemResource("D:\\softwaretools\\eclipse-workspace\\Spring-Example\\src\\main\\resources\\applicationContext.xml"));
//通过容器获取test实例
Student tt = (Student)beanFac.getBean("stu");
System.out.println(tt.getName());;
}
}
-
- ApplicationContext接口
org.springframework.context.ApplicationContext 是IOC容器的非常重要的一个接口,它继承了BeanFactory接口的基本功能,同时也继承了容器容器的高级功能如MessageSouce(国际化资源接口)、ResourcesLoader(资源加载接口)、ApplicationEventPublisher(应用事件发布接口)等,通过上述的描述,在实际的开发应用中我们必然会选择功能强大的ApplicationContext接口.
ApplicationContext接口有三个实现类:
1、ClassPathXmlApplicationContext 从类的路径中加载IOC容器配置 --目前案例使用
2、FileSystemXmlApplicationContext 从文件路径加载IOC容器
3、XmlWebApplicationContext 从web系统的xml文件中读取配置并加载IOC容器
测试实例:
<bean id="books" class="com.its.pojo.Books">
<property name="author" value="张三"/>
<property name="title" value="张三流浪记"/>
</bean>
@Test
public void T0() {
//初始化容器并加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//获取容器中的bean对象
Books books = (Books) context.getBean("books");
System.out.println(books);
}
测试结果:
-
- BeanFactory接口和ApplicationContext接口的区别【面试题】
1. 加载方式
BeanFactory在启动的时候不会去实例化bean,只有从容器中拿bean的时候才去实例化,应用启动的时候占用的资源比较少。
ApplicationContext 在启动的时候就把所有的bean默认全部实例化,占用资源,但是可以通过lazy-init=true来配置bean的延迟加载。
2. BeanFactory方法比较旧,初始化容器的时候需要绝对路径查找文件。ApplicationContext本身提供3种方式,相对、绝对、web.xml
- 注入
-
- setter 方法注入 构造器注入
setter 方法注入
构造器注入:
测试:
-
- Spring注解注入
目前企业级项目越来越庞大,Spring配置的bean数量也会越来越庞大,这样会导致配置文件繁杂,难以管理,而注解是Spring另一种配置方式,像一种修饰符一样,应用于包、类型、方法、成员变量中,解放繁杂的配置文件。
Spring中常用的注解:
@Component 标识一个受Spring管理的基本组件(加载到IOC容器中)
@Repository标识持久层组件类
@Service 标识业务层组件类
@Controller 标识控制层组件类
@Resource 自动装配DI
@Autowired 自动装配
实例:
-
- @Autowired和@Resource区别
@Autowired自动装配可以对成员变量、方法、和构造函数进行标注,来完成自动装配工作,使用@Autowired就不用再使用setter和构造注入, @Autowired会根据类型(byType)进行自动装配,使用的时候先去容器中查询注解的类型的bean,如果查询结果为一个,就将该bean装配给@Autowired指定的数据,如果结果不止一个@Autowired会根据名称匹配(byName),如果查询结果为空则抛出异常
@Resource自动装配首选声明这个注解并不是Spring注解,它是javax.annotation.Resource,Spring默认支持这个注解的注入,@Resource有两个主要的属性, name和type,而Spring默认将name属性解析为bean的名字,而type解析为bean的类型,如果注解时使用name属性,则默认使用ByName注入策略,而使用type属性时则默认使用byType自动注入策略,如果都不指定,则通过反射机制使用byName注入策略
两种自动装配方式的比较【经典面试题】:
相同点:两者都可以写在字段和setter方法上,如果写在字段上(属性),两个都能完成自动装配工作。
不同点:
@Autowired默认按照byType方式进行bean装配,@Resource默认按照byName方式进行bean装配
@Resource不是Spring注解,@Resource是JAVAEE注解。
例子:
- AOP(面向切面编程)
在软件业,AOP为Aspect[ˈæspekt] Oriented[ˈɔːrientɪd] Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
“面向切面编程”,这样的名字并不是非常容易理解,且容易产生一些误导。有些人认为“OOP即将落伍,AOP是新一代软件开发方式”。显然,发言者并没有理解AOP的含义。Aspect,的确是“方面”的意思。不过,汉语传统语义中的“方面”,大多数情况下指的是一件事情的不同维度、或者说不同角度上的特性,比如我们常说:“这件事情要从几个方面来看待”,往往意思是:需要从不同的角度来看待同一个
事物。这里的“方面”,指的是事物的外在特性在不同观察角度下的体现。而在AOP中,Aspect的含义,可能更多的理解为“切面”比较合适。
说的直白点,就是以前大家关注点都是从视图层-控制层-业务层-持久化层-数据库,但是面向切面编程AOP就是在其中的某一层设置一道关卡,但凡通过这层的请求都会被拦截然后做一些操作,如果想要实现拦截,我们需要通过代理实现。
-
- 代理模式
在代码中代理为其他对象提供一种代理以控制对这个对象的访问”,简单点说就是,之前A类自己做一件事,在使用代理之后,A类不直接去做,而是由A类的代理类B来去做。代理类其实是在之前类的基础上做了一层封装
代理模式的优点:
被代理类只需要专注于自己的核心代码即可,剩下的交给代理类就可以了,使得代码更加简洁,分工明确
-
-
- 静态代理
-
实例:、
创建一个电影的接口
创建电影1的类
电影2的类
代理类
测试:
-
-
- JDK动态代理
-
通过接口的方式,让代理类和实际业务类实现统一的接口,并且借助代理类统一管理接口InvocationHandler(影院的接口)进行动态代理机制的实现。这种方式依赖于接口,如果一个类不实现接口则无法实现代理。
代理类要实现InvocationHandler接口
例子:
电影接口:
第一个电影实现类
第二个电影实现类
代理类:
测试类:
-
-
- cglib动态代理
-
cglib采用了非常底层的字节码技术(反射),其通过字节码技术为一个类创建子类,并在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势织入横切逻辑,因为是使用继承,所以不能对final修饰的类进行代理。
CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如Spring AOP为他们提供 方法的interception(拦截)
代理类要实现MethodInterceptor接口,可以不需要接口
实现类1
实现类2
代理类
测试类
- 通过Aspects实现Spring AOP
AspectJ是一个基于Java语言的AOP框架。从Spring 2.0以后引入了AspectJ的支持。目前的Spring框架,建议开发者使用AspectJ实现Spring AOP。使用AspectJ实现Spring AOP的方式有两种:一是基于XML配置开发AspectJ(较过时),一是基于注解开发AspectJ(目前流行)。
切面:
指当前aop设定的一个方面,这个方面可以包含多个类(一般情况下制定某一个具体的包,实际注解中,切面注解到类,指定为切面类)
切点:
点指的是具体的某一个类中的方法。execution(*com.it.service.AnimalService.addAnimal(..))
AspectJ实施增强的类需要配置为切面,AspectJ提供了下列注解用于配置切面,注解如下:
@Aspect 配置一个类为切面类
@Before 配置一个方法为前置增强
@After 配置一个方法为后置增强
@AfterReturning 配置一个方法为返回后增强
@AfterThrowing 配置一个方法为抛出异常后增强
@Around 配置一个方法为环绕增强
@DeclareParents 配置一个属性为引介增强(类级别)
-
- 头文件
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
-
- 开启扫描和启动基于注解的AspectJ支持
<!-- 开启扫描 -->
<context:component-scan base-package="com.its"/>
<!-- 配置AspectJ支持 -->
<aop:aspectj-autoproxy/>
-
-
- 需要添加的包
-
<!-- 配置aspectj时使用-->
<!-- https://mvnrepository.com/artifact/aspectj/aspectjrt -->
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aspectj/aspectjweaver -->
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
控制层的类:
业务层的类:
持久化层的类:
切面类
结果: