什么是框架
制定一套规则,在该规则下工作,别人做的舞台,你表演
特点
封装了特定的处理流程,和控制逻辑
和类库的区别
是封装了逻辑的高内聚的,类库是松散的工具组合
框架注重于某一领域,类库则是更通用的'
为什么使用
软件系统复杂
重用度高,效率提高
专注于领域了解
spring简介
为了解决企业应用复杂性而开发的,不仅用在企业应用开发
是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架
同过控制反转达到松耦合的目的
允许通过分离应用的业务逻辑和系统服务进行高内聚开发
包含管理应用对象的生命周期,这个意义上是一个容器
将简单的组件配置,组合成更复杂的框架,这个意义上是框架
作用
- 容器
- 提供了对多种技术的支持
- AOP(事物管理,日志)
- 方便应用的辅助类
- 主流应用框架提供良好的支持
接口
是沟通的中介物的抽象
实体把自己提供给外界的抽象化说明,不公开内部实现,只公开方法
java8接口可以拥有方法体
面向接口编程
结构设计中,分清楚层次及调用关系,每层只向上层提供一组功能接口,每层只依赖接口而不是实现类
接口实现的变动不影响各层的调用
IOC
控制反转:控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器创建和维护(需要对象的时候不是用new,而是向容器申请)
DI(依赖注入)是其中一种实现方式(获得依赖对象的过程自身管理变为了IOC容器主动注入)ioc的实现方法
目的:创建对象并且组装对象之间的关系
在IOC容器中所有的对象都叫做bean
使用spring创建对象
下载jar地址
创建配置文件(applicationcontext)
<?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">
</beans>
在配置文件中添加bean
id为自己起的名字,class为实现类的全路径 id也可以换为name
id使用了唯一的约束,里面不能出现特殊字符
name没有使用唯一约束
创建哪一个对象就把对象所对应的类写在class中,就会自动的创建对象,相当于一个工厂 ,根据全路径使用反射创建类
<bean id="userDao" class="com.szg.demo1.UserDaoImpl"></bean>
创建一个对象
@Test
public void Test(){
//加载配置文件
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
//根据id获取对象
UserDao userDao = (UserDaoImpl)applicationContext.getBean("userDao");
//执行对象方法
userDao.save();
userDao.delete();
}
依赖注入
name表示要注入的名称
name 的值set后面首字母小写就行 不一定是属性名 按set方法来注入
value表示要注入的值
属性要提供set方法
//创建对象时就会赋值
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
<property name="name" value="11111"></property>
</bean>
spring工厂类
applicationcontext:加载配置文件的时候就创建好对象,然后在根据id获取
在通过getBean获取对象
applicationcontext工厂类
ClassPathXmlApplicationContext:加载类路径下的配置文件
FileSystemXmlApplicationContext:加载文件系统下的配置文件
spring bean对象的生命周期
设置对象的生命周期方法
init-method方法:初始化的时候执行的方法
destory-method:被销毁时创建的方法(bean是单例的)
使用close关闭applicationcontext时结束
spring bean的作用范围
scope="singleton":默认使用单例模式
scope="prototype"默认使用多例模式,对象不是工厂关闭时销毁,而是垃圾回收
request:应用在web项目中,Spring创建这个类以后,将这个对象存入到request范围中。
session:应用在web项目中,Spring创建这个类以后,将这个对象存入到session范围中
globalsession:应用在web项目中,必须在porlet(基于Java的Web组件,子域名)环境下使用。但是如果没有这种环境,相对于session.
spring 工厂实例化的方法
无参构造:默认(调用无参构造方法)
factory-method="create":在类中创建一个create方法,必须静态,必须有返回值
factory-bean=""也可以实例化另一个对象:在""中写入另一个bean的id
分模块配置
新建一个xml,然后引入
<import resource="sss.xml"></import>
属性注入
<bean id="userDao" class="com.szg.demo1.UserDaoImpl" init-method="init" destroy-method="destorys" >
<constructor-arg name="name" value="5545"></constructor-arg>
</bean>
//实体类建立构造方法
public UserDaoImpl(String name){
this.name=name;
}
对象属性数据类型的注入
<bean id="useDao" class="com.szg.demo1.UseDao" >
<property name="name" value="wc"></property>
</bean>
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
<constructor-arg name="name" value="5545"></constructor-arg>
<property name="useDao" ref="useDao"></property>
</bean>
p名称空间属性注入
<bean id="useDao" class="com.szg.demo1.UseDao" p:name="wc">
</bean>
<bean id="userDao" class="com.szg.demo1.UserDaoImpl" p:useDao-ref="useDao">
<constructor-arg name="name" value="5545"></constructor-arg>
</bean>
spring spEL表达式
<bean id="useDao" class="com.szg.demo1.UseDao">
<property name="name" value="#{'234'}"></property>
</bean>
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
<constructor-arg name="name" value="5545"></constructor-arg>
<property name="useDao" value="#{useDao}"></property>
//也可以选择其他类属性来进行赋值 假设name是一个字段
<property name="useDao" value="#{useDao.name}"></property>
</bean>
spring list 集合类型属性注入
数组类型(使用list,list集合也可以)
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
<constructor-arg name="name" value="5545"></constructor-arg>
<property name="useDao">
<list>
<value>1</value>
<value>2</value>
</list>
</property>
</bean>
set类型注入
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
<constructor-arg name="name" value="5545"></constructor-arg>
<property name="useDao">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
</bean>
map类型注入
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
<constructor-arg name="name" value="5545"></constructor-arg>
<property name="useDao">
<map>
<entry key="key1" value="value1"></entry>
</map>
</property>
</bean>
spring注解开发
ioc注解开发
-
要使用注解形式必须使用aop包
-
在配置文件中引入context约束
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
<context:component-scan base-package="com.szg.demo1"></context:component-scan>
@Component("userDao")//在类上使用 相当于bean的id
@Scope("prototype")//设置范围为多里
///////////////////////////////////////////////////////
//属性注入
/* @Autowired//根据类型注入
@Qualifier("UseDao")//根据名称来进行注入*/
@Resource(name = "useDao")
注解生命周期
@PostConstruct
public void init(){
System.out.println("你好");
}
@PreDestroy
public void destorys(){
System.out.println("再见");
}
spring aop
面向切面编程
通过预编译方式和运行时期动态代理实现程序功能的统一维护的一种技术
不破坏原来的类,生成一个代理类,在原来类的基础上进行增强,可以随时添加功能, 取消添加的功能
使用aop要引入aspectjweaver-1.9.2.jar包,并且要引入aop约束
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
spring test
使用spring-test在测试时就不用每次获取工厂
@RunWith(SpringJUnit4ClassRunner.class)
//配置文件路劲
@ContextConfiguration("classpath:applicationContext.xml")
aop配置
1.编写一个切面类,里面有要添加的功能
2.将切面类交给spring-bean来管理
3.配置aop完成对目标的代理
切入点:给目标类里的哪个方法进行增强 格式(* 全路径(参数)) *代表返回值,
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
</bean>
<bean id="useDao" class="com.szg.demo1.UseDao">
</bean>
<aop:config>
<!--接入点 给目标类的哪个方法进行增强-->
<aop:pointcut id="point" expression="execution(* com.szg.demo1.UserDaoImpl.save(..))"></aop:pointcut>
<!--配置切面 增强的功能是什么 ref是增强功能所在的类-->
<aop:aspect ref="useDao">
<aop:before method="check" pointcut-ref="point"></aop:before>
</aop:aspect>
</aop:config>
通知
前置后置通知
<bean id="userDao" class="com.szg.demo1.UserDaoImpl">
</bean>
<bean id="useDao" class="com.szg.demo1.UseDao">
</bean>
<aop:config>
<!--接入点 给目标类的哪个方法进行增强-->
<aop:pointcut id="point" expression="execution(* com.szg.demo1.UserDaoImpl.save(..))"></aop:pointcut>
<!--配置切面 增强的功能是什么 ref是增强功能所在的类-->
<aop:aspect ref="useDao">
<aop:before method="check" pointcut-ref="point"></aop:before>
<!--后置通知 可以获得切入点的返回值 名字必须和参数一致-->
<aop:after-returning method="log" pointcut-ref="point" returning="ref"></aop:after-returning>
</aop:aspect>
</aop:config>
环绕通知
可以让切入方法不执行
异常通知
<!--异常通知-->
<aop:after-throwing method="log" pointcut-ref="point"></aop:after-throwing>
最终通知
无论如何最终都会执行
<aop:after method="log" pointcut-ref="point"></aop:after>
spring 切入点表达式
<aop:pointcut id="point" expression="execution(* com.szg.demo1.UserDaoImpl+.save(..))"></aop:pointcut>
+.:表示当前类和子类
aop注解开发
首先在要配置文件中开启注解
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
然后在切面类上添加注解
@aspect
在切面增强方法钱加上通知
@Before(value="execution(* com.szg.demo1.UserDaoImpl+.save(..))")
注解通知类型
* @Before --- 前置通知
* @AfterReturning --- 后置通知
* @Around --- 环绕通知(目标对象默认不执行,需要手动执行)
* @After --- 最终通知
* @AfterThrowing --- 异常抛出通知
有返回值再表达式后用,号隔开加上returning="ref"
spring jdbc Template
使用jdbc模板
public void t(){
//创建连接池 存储数据库相关信息
DriverManagerDataSource driver = new DriverManagerDataSource();
//设置驱动名称
driver.setDriverClassName("com.mysql.cj.jdbc.Driver");
//设置数据库地址
driver.setUrl("jdbc:mysql://localhost:3306/examse?useSSL=false&serverTimezone=Hongkong");
driver.setUsername("root");
driver.setPassword("123456");
//使用jdbc模板
JdbcTemplate jdbcTemplate = new JdbcTemplate(driver);
jdbcTemplate.update("insert into account values (9,?,?)","sun","5000");
}
使用spring来完成jdbc模板的改写
<!--配置drivermanagerdatasource-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/examse?useSSL=false&serverTimezone=Hongkong"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"></property>
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:aaa.xml")
public class JdbcTest2 {
@Resource(name = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Test
public void t(){
jdbcTemplate.update("insert into account values (10,?,?)","sun","5000");
}
}
略.............
spring 事物管理
platform transactionmanager:平台事物管理器,是一个接口,下面有两个实现类
DataSourcetransactionmanager:底层使用jdbc事物管理
hibernatetransactionmanager:底层使用hibernate事物管理
transactiondefinition:事物定义信息,用于定义事物相关信息,隔离级别,超时信息,传播行为,是否只读
transactionstatus:事物状态,用在记录事物管理过程中事物的状态
事物的传播行为
一个业务方法调用另外一个业务方法的时候,事物是怎么进行传播的,所有的事物在业务层做
spring7中事物传播行为
保证多个操作在同一个事务中
<假设有两个方法A和B 在B中调用A>
PROPAGATION_REQUIRED
默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来
PROPAGATION_SUPPORTS
支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
PROPAGATION_MANDATORY
如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。
保证多个操作不在同一个事务中
PROPAGATION_REQUIRES_NEW
如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。也就是不包含A
PROPAGATION_NOT_SUPPORTED
如果A中有事务,将A的事务挂起。不使用事务管理。
PROPAGATION_NEVER
如果A中有事务,报异常。
嵌套式事物
PROPAGATION_NEVER
A中有事物,在B中调用A,执行A,在A中设置一个保存点,向后执行,没问题结束,有问题可以选择是回到保存点的位置,还是回到开头的位置