1、Spring
1.1、简介:
-
Spring是一个轻量级控制反转(loC)和面向切面(AOP)的容器框架。
-
Spring是一个开源的免费的框架(容器)。
-
Spring是一个轻量级的、非入侵式的框架。
-
控制反转(IOC)与面向切面编程(AOP)
-
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.10.RELEASE</version> </dependency>
1.2、组成:
-
核心容器(Spring Core)
-
核心容器提供Spring框架的基本功能。Spring以bean的方式组织和管理Java应用中的各个组件及其关系。Spring使用BeanFactory来产生和管理Bean,它是工厂模式的实现。BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开。
-
应用上下文(Spring Context)
-
Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,如JNDI、EJB、电子邮件、国际化、校验和调度功能。
-
Spring面向切面编程(Spring AOP)
-
通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring框架中。所以,可以很容易地使 Spring框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
-
JDBC和DAO模块(Spring DAO)
-
JDBC、DAO的抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理,和不同数据库供应商所抛出的错误信息。异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。
-
对象实体映射(Spring ORM)
-
Spring框架插入了若干个ORM框架,从而提供了ORM对象的关系工具,其中包括了Hibernate、JDO和 IBatis SQL Map等,所有这些都遵从Spring的通用事物和DAO异常层次结构。
-
Web模块(Spring Web)
-
Web上下文模块建立在应用程序上下文模块之上,为基于web的应用程序提供了上下文。所以Spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
-
MVC模块(Spring Web MVC)
-
MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的。MVC容纳了大量视图技术,其中包括JSP、POI等,模型来有JavaBean来构成,存放于m当中,而视图是一个街口,负责实现模型,控制器表示逻辑代码,由c的事情。Spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境。Spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问的对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用。
2、IOC理论推导
1.UserDao接口
2.UserDaoImpl实现类
3.UserService业务接口
3.UserServicelmpl业务实现类
private UserDao userDao;
//利用set接口实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
使用set注入后,程序不在具有主动性,而是变成了被动接受的对象!
3、第一个程序 HelloSpring
3.1代码部分
public static void main(String[] args) {
//使用配置文件方式的必须写此行代码
//获取spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象都在spring容器中,我们要使用调用即可
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
<?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">
<!--使用spring来创建对象,spring中所有对象叫bean
id = 变量名
class = new 的对象
property 相当于给对象中的属性设置一个值
-->
<!--
ref表示引用spring已经创建好的对象
value有一个具体的值
-->
<bean id="hello" class="com.jh.pojo.Hello">
<property name="str" value="spring"/>
</bean>
</beans>
3.2官方文档原文
3.3注意:
Hello对象是由Spring创建的,Hello对象的属性也是Spring容器设置的。这个过程就叫控制反转。
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring之后,对象是由Spring来创建的。
反转:程序本身不创建对象,而变成被动的接收对象。
依赖注入:就是利用set方法来进行注入。
IOC是一种编程思想,由主动的编程变为被动的接收。
4、IOC创建对象的方式
1.使用无参构造器创建对象
2.有参构造器创建对象
1.下标赋值
<bean id="hello" class="com.jh.pojo.Hello"> <constructor-arg index="0" value="芜湖"/> </bean>
2.类型创建
<bean id="hello" class="com.jh.pojo.Hello"> <constructor-arg type="java.lang.String" value="起飞"/> </bean>
3.直接使用参数名
<bean id="hello" class="com.jh.pojo.Hello"> <constructor-arg name="str" value="大赛的撒"/> </bean>
在配置文件加载的时候,容器中管理的对象就已经初始化了!
5、Spring配置
5.1 alias(别名)
<alias name="hello" alias="hello2"/>
5.2 Bean的配置
<!--使用spring来创建对象,spring中所有对象叫bean
id = 变量名
class = new 的对象
property 相当于给对象中的属性设置一个值
-->
<!--
ref表示引用spring已经创建好的对象
value有一个具体的值
-->
<bean id="hello" class="com.jh.pojo.Hello" name="name2,u2 u3;u4">
<property name="str" value="spring"/>
</bean>
5.3 import
一般用于团队开发,可以将多个合并成一个。多个beans。xml文件合并成一个applicationContext.xml文件
6、依赖注入(DI)
6.1 构造器注入
见第四部分
6.2 set方式注入
依赖注入:set注入!
依赖:bean对象的创建依赖于容器!
注入:bean对象中的所有属性,由容器注入!
<?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">
<bean id="address" class="com.jh.pojo.Address"/>
<bean id="student" class="com.jh.pojo.student">
<!--第一种 普通值注入-->
<property name="name" value="请求"/>
<!--第二种 Bean注入-->
<property name="address" ref="address"/>
<!--第三种 数组注入-->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!--第四种 List注入-->
<property name="hobby">
<list>
<value>听歌</value>
<value>动漫</value>
<value>游戏</value>
</list>
</property>
<!--第五种 Map集合-->
<property name="card">
<map>
<entry key="身份证" value="111"/>
<entry key="银行卡" value="000"/>
</map>
</property>
<!--第六种 Set集合-->
<property name="games">
<set>
<value>LOL</value>
<value>APEX</value>
</set>
</property>
<!--第七种 null值注入-->
<property name="wife">
<null></null>
</property>
<!--第八种 properties-->
<property name="info">
<props>
<prop key="学号">202121</prop>
<prop key="性别">男</prop>
</props>
</property>
</bean>
</beans>
6.3 拓展方式注入
6.3.1 P命名空间
xmlns:p="http://www.springframework.org/schema/p"
6.3.2 C命名空间
xmlns:c="http://www.springframework.org/schema/c"
6.4 bean的作用域
1.单例模式(Spring默认机制)
2.原型模式:每次从容器种get的时候会产生新的对象
3.request、session、application都在web开发种使用。
7、Bean的自动装配
-
自动装配是Spring满足bean依赖一种方式!
-
Spring会在上下文中自动寻找,并自动给bean装配属性!
在Spring中由三种装配方式
1.在xml中显示的配置
2.在Java中显示配置
3.隐式的自动装配bean
7.1测试
7.2 byName自动装配
<!-- byName会自动在容器上下文寻找,和自己对象set方法后面的值对应的beanid-->
<bean id="cat" class="com.jh.pojo.Cat"/>
<bean id="dog" class="com.jh.pojo.Dog"/>
<bean id="people" class="com.jh.pojo.People" autowire="byName">
<property name="name" value="全为"/>
7.3 byType自动装配
<!--byName会自动在容器上下文寻找,和自己对象属性类型对应的beanid-->
<bean id="cat" class="com.jh.pojo.Cat"/>
<bean id="dog" class="com.jh.pojo.Dog"/>
<bean id="people" class="com.jh.pojo.People" autowire="byType">
<property name="name" value="全为"/>
</bean>
-
byName的时候必须保证所有bean的id唯一,和这个bean需要和自动注入的属性set方法的值一致。
-
byType的时候必须保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致。
7.4使用注解实现自动装配
使用注解须知:
1.导入约束。context约束
2.配置注解的支持。context:annotation-config/
<?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方法上使用。
-
使用Autowired可以不写set方法,前提是自动装配属性在IOC容器存在,且符合名字byName。
@Nullable 字段标记了这个注解,说明这个字段可以为null;
public void setDog(@Nullable Dog dog) {
this.dog = dog;
}
@Autowired(required = false)
private Dog dog;
如果@Autowired自动装配环境比较复杂,可以使用@Qualifier(value="xxxx")去配置,指定唯一的对象注入。
@Autowired(required = false) @Qualifier(value = "dog111") private Dog dog;
java自带注解@Resource
@Resource和@Autowired的区别:
-
都用来自动装配,都可以放在属性字段上
-
@Autowired默认通过byType 的方式实现,@Resource默认byName方式
8、使用注解开发
用注解开发必须导入aop包
@Autowired:自动装配通过类型,名字。如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value="xxx")
@Nullable 字段标记了这个注解,说明这个字段可以为null
@Resource 自动装配通过名字,类型
@Component 组件,放在类上,说明这个类杯Spring管理了,就是bean
@Value
@Repository
@Service
@Controller
@Scope
1.bean
2.属性如何注入
@Component
public class User {
//相当于 <property name="name value="芜湖起飞"/>
@Value("芜湖起飞")
public String name;
// public String name = "芜湖起飞";
public String getName() {
return name;
}
@Value("芜湖起飞1")
public void setName(String name) {
this.name = name;
}
}
3.衍生的注解
@Component有几个衍生注解,我们在web开发中,,会按照mvc三层架构分层。
-
dao【@Repository】
-
service【@Service】
-
controller【@Controller】
-
这四个注解功能一样,都是将某个类注册到Spring中,装配Bean
4.自动装配
@Autowired:自动装配通过类型,名字。如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value="xxx")
@Resource 自动装配通过名字,类型
5.作用域
@Scope("范围")
6.小结
xml与注解:
-
xml更加万能,适用于任何场合
-
注解 不是自己的类使用不了,维护相对复杂
xml与注解最佳实践:
-
xml用来管理bean。
-
注解只负责属性的注入。
9、使用java的方式配置Spring
现在不需要使用Spring的xml配置,全部交给java。
配置类:
@Configuration
public class AppConfig {
@Bean
public MyServiceImpl myService() {
return new MyServiceImpl();
}
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
10、代理模式
代理模式的分类:
-
静态代理
-
动态代理
10.1静态代理
角色分析:
抽象角色:一般会使用接口或者抽象类解决。
真实角色:被代理的角色。
代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
客户:访问代理对象的人。
代理模式的好处:
-
可以使真实角色的操作更加纯粹,不用去关注一些公共业务。
-
公共业务交给代理角色,实现了业务分工。
-
公共业务发生扩展的时候,方便集中管理。
缺点:
-
一个真实角色会产生一个代理角色,代码量翻倍。
10.2动态代理
-
动态代理和静态代理角色一样
-
动态代理和代理类是动态生成的,不是我们直接写好的
-
动态代理分为两类:基于接口的动态代理,基于类的代理
基于接口:JDK动态代理
基于类:cglib
java字节码实现:javasist
需要了解两个类:Proxy,invocationHandler
11、AOP
11.1 什么是AOP
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译的方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数时编程的一种衍生范型。利用AOP可以对业务逻辑各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发效率。
-
Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
-
Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
-
Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
-
Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
-
Target(目标对象):织入 Advice 的目标对象.。
-
Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关,但是我们需要关注的部分就是横切关注点。如日志,安全,缓存,事务等等
11.2使用Spring实现AOP
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
导入bean后,输入aop:comfig加载命名空间
方式一:使用Spring的API接口
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext02.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userService");
userService.add();
}
方式二:自定义类
<!-- 自定义类-->
<bean id="diy" class="com.jh.Diy.DiyPointCut"/>
<aop:config>
<!-- 自定义切面-->
<aop:aspect ref="diy">
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.jh.service.UserServiceImp.*(..))"/>
<!-- 通知-->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
方式三:注解实现
12、整合Mybatis
1.编写数据源
2.sqlSessionFactory
3.sqlSessionTemplate
4.需要加实现类
5.将自己写的实现类,注入到spring里面
6.测试使用
13、声明式事务
-
把一组业务当成一个业务来做,要么都成功,要么都失败
-
事务在项目开发中,十分重要,涉及到数据的一致性问题,不能马虎
-
确保完整性和一致性
事务ACID原则:
-
原则性
-
一致性
-
隔离性
多个业务可能操作同一个资源,方式数据损坏
-
持久性
事务一旦提交,无论系统发生什么问题,结果都不会被影响。被持久化写到存储器中。