1、Spring
1.1、简介(优点)
- Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器。
- 轻量级、低侵入 、松耦合
- 框架粘合剂,更容易整合其他框架
- 支持事务处理
官网:https://spring.io/projects/spring-framework#overview
GitHub:https://github.com/spring-projects/spring-framework
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.4</version>
</dependency>
1.2、组成
1.3、IOC
** 控制反转(Invertion of control)是一种设计思想,DI(依赖注入)是实现IOC的一种方式。**在没有IOC思想的程序中,对象的创建和管理都由开发者来控制,控制反转后,对象的创建和管理交由第三方,因此,控制反转是获取对象的方式反转了的意思
** 控制反转是一种通过描述(XML或者注解)并通过第三方去生产或获取特定对象的方式。在spring中实现控制反转的是Ioc容器,其实现方式是依赖注入(Dependendy Injection)。**
1.4、IOC创建对象的几种方式
1、默认使用无参构造
2、若需使用有参构造创建对象
-
通过下标赋值
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0" value="7500000"/> <constructor-arg index="1" value="42"/> </bean>
-
通过类型创建(不推荐)
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> <constructor-arg type="java.lang.String" value="42"/> </bean>
-
通过参数名(推荐)
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg name="years" value="7500000"/> <constructor-arg name="ultimateAnswer" value="42"/> </bean>
总结:spring在加载配置文件的时候,就会初始化所管理的对象
1.5、Spring 配置
-
别名
<!--如果添加了别名,可以通过别名来获取这个类的对象--> <alias name="student" alias="flowers"/>
-
Bean配置
<!-- id:bean的唯一标识符 class:bean对象所对应的全限定名:包名+类型 name:别名,可同时取多个别名 --> <bean id="User" class="com.yijin.User" name="user u u2 u4"> <property name="name" value="依锦"> </bean>
-
import
import是将多个配置文件导入合并成一个总文件<import resource=“beans.xml”/> <import resource=“beans2.xml”/> <import resource=“beans3.xml”/>
1.6、依赖注入
- 构造器注入
- Set方式注入
- 真实测试对象
public class Student { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String,String> card; private Set<String> games; private String girlfriend; private Properties info;
-
复杂类型
public class Address { private String address;
-
beans.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd " > </beans>
-
测试类
public class Test3 { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:spring/bean*.xml"); Student student= (Student) applicationContext.getBean("student"); System.out.println(student); } }
-
完善注入信息
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd " > <bean id="student" class="com.newer.pojo.Student" p:name="依锦啊" c:address=""> <property name="address" ref="address"/> <property name="books"> <array> <value>红楼梦</value> <value>西游记</value> <value>水浒传</value> <value>三国演义</value> </array> </property> <property name="hobbys"> <list> <value>学习</value> <value>看书</value> <value>玩游戏</value> <value>敲代码</value> </list> </property> <property name="card"> <map> <entry key="身份证" value="123456789"/> <entry key="银行卡" value="321456987"/> </map> </property> <property name="girlfriend"> <null/> </property> <property name="info"> <props> <prop key="年级">小学三年级</prop> <prop key="学号">ja180902</prop> </props> </property> </bean> <bean id="address" class="com.newer.pojo.Address"> <property name="address" value="上海"/> </bean> </beans>
- 真实测试对象
1.7、bean作用域
1、单例模式(默认)
<!-- the following is equivalent, though redundant (singleton scope is the default) -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
2、原型模式:每次从容器中get的时候会产生新的对象
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
3、其余的request、session、application 这些只能在web中使用
1.8、Bean自动装配
-
自动装配是Spring满足bean依赖的一种方式,Spring会在上下文中自动寻找,并给bean装配属性!
-
Spring提供三种装配bean的方式
1、在xml中显示的装配
2、在Java中显示的装配
3、隐式的自动装配bean自动装配有三个类型
<bean class="com.yijin.Cat"/> <bean class="com.yijin.Dog"/> <!-- byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid byType:会自动在容器上下文中查找,和自己对象属性相同的bean --> <bean id="people" class="com.yijin.People" autowire="byType"> <property name="name" value="依锦"> </bean>
小结:
- byName的时候,需要保证beanid的唯一,并且这个bean需要和自动注入的属性的set方法的值一致
- byType需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
1.9、使用注解进行自动装配
- 导入配置
<?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">
<context:annotation-config/>
</beans>
@Autowired:直接在想要自动装配的属性上使用,也可以在set方法使用
该注解且存在一个required属性,如果显示定义了required属性为false,说明这个对象可以为null,
否则不允许为空
如果@Autowired 自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=“xxx”)去配置@Autowired的使用,指定唯一的bean对象注入
public class People{
@Autowired
@Qualfier(value = "cat111 ")
private Cat cat;
}
@Resource:同上一个注解一样是自动装配的效果
区别:
- 都是用来自动装配,用来放在属性字段之上
- @Autowired 通过byType实现,而且必须要求这个对象名存在
- @Resource默认通过byName方式实现,若找不到名字,则通过byType实现,若都找不到则报错
2、使用注解开发
在Spring4.0之后,要使用注解开发必须要保证aop包的导入
-
bean
-
属性的注入
@Value(“xxx”) -
衍生的注解
@Component有几个衍生的注解,我们在web开发中,会按照mvc三层架构分层
dao[@Repository]
service[@Service]
controller[@Controller]
这四个注解代表一样的意思(将某个类注入到spring容器中) -
自动装配
@Autowired:通过类型名字
@Nullable :表示标记的字段可以为空
@Resource:通过名字类型 -
小结
xml与注解:
xml更加万能,适用于任何场合,维护方便简单
注解简易配置,但维护相对复杂,只能适用自己的类
3. 完全使用Java配置Spring
Spring最新版本可以完全使用Java类和注解代替xml文件
3、代理模式
代理模式由抽象角色、代理角色、真实角色所组成,是为其他对象提供一种代理以控制对该对象的一个访问,代理对象可以在客户端和目标对象起到中介的作用,以此保护真实对象,SpringAOP 的底层实现原理就为代理模式
3.1、静态代理
角色分析:
- 抽象角色:一般使用接口或抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色之后,会做一些附属操作
- 客户:访问代理角色
代理模式好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 繁琐的东西交给代理角色,实现业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色;代码量增多,开发效率变低
3.2、动态代理
- 动态代理和静态代理的角色一样
- 动态代理的动态类是直接生成的,不是自己写好的
- 动态代理分为两大类,基于接口的动态代理和基于类的动态代理
- 基于接口:jdk动态代理
- 基于类:cglib
- Java字节码实现:Javassist
需要了解2个类:proxy、InvocationHandler
动态代理的优点:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 繁琐的东西交给代理角色,实现业务的分工
- 公共业务发生扩展的时候,方便集中管理
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只需要实现同一个接口
4、AOP
4.1、什么是AOP
AOP为Aspect Oriented Programming的缩写,是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术