一.Spring框架概述
1,Spring是一个 开源的 轻量级的 JavaEE框架。
轻量级:体积小,jar独立应用不须要依赖其余jar包,
开源:收费,能够提供源代码
框架:解决开发的复杂性,简化企业开发。
2,spring的两个外围局部:IOC,Aop
IOC:管制反转,把创建对象的过程交给spring进行治理。
Aop:面向切面,在不批改源代码的状况下,进行性能的增加或加强。
3,spring框架的特点:
1),不便解耦,简化开发:对象与对象之间的关系依赖spring。
2),Aop编程反对:不扭转源代码,加强性能
3),不便测试;
4),不便集成各种优良框架。
5),不便进行食物治理,升高API的应用难度
6),java源码经典学习范例。
4,入门案例:
1),下载Spring5:
spring网址 : spring.io
间接下载地址:https://repo.spring.io/artifa…
还要下载一个日志jar包,spring5依赖于这个jar包commons-login这个jar
下载链接:commons-logging-1.1.1.jar下载及Maven、Gradle引入代码,pom文件及包内class -时代Java (nowjava.com)
我集体下载5.2.6
2),下载实现当前,加入一个一般的java我的项目,将jar导入我的项目
3),应用spring
(1),创立一般类,在类中创立一般办法
public class User {
public void add(){
System.out.println("add.......");
}
}
(2),创立spring配置文件,在配置文件中配置文件配置创立的对象
a,Spring配置文件应用xml文件配置
<?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">
<!--配置User对象创立-->
<bean id = "user" class = "com.yuge.User"></bean>
</beans>
b,创立测试类Test
public class Tset {
@Test
public void testAdd(){
//1.读入上下文配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//2.获取配置对象
User user = context.getBean("user", User.class);
System.out.println(user);
user.add();
}
}
c,测试后果,胜利创建对象,并调用办法
二,IOC容器
1.IOC底层原理
1),什么是IOC:
管制反转,将对象的创立和对象之间的交互作用,都交给spring进行治理。
2),应用IOC的目标
为了升高耦合
3)IOC入门案例
2,IOC底层原理
1),xml解析,工厂模式,反射
2)图解IOC底层原理
传统形式:
工厂模式:
IOC模式:
3.IOC接口(BeanFactory)
IOC基于容器实现,IOC容器的底层就是对象工厂
1),BeanFactory接口:
IOC容器的最根本实现,是spring外部的应用接口,不提倡给开发人员应用。
2),ApplicationContext接口:
是BeanFactory的子接口,提供比BeanFactory更弱小的性能,个别为开发人员应用
3),两接口的区别
因为咱们在应用Spring框架时,个别都是配合网页应用,应用BeanFactory创建对象时,不会创建对象,而加载配置文件的时候,是在服务器启动的时候,应用tomcat,都是将零碎加载文件等麻烦非空间的事放在tomcat启动时实现,以提供更好的用户体验,所以采纳ApplicationContext接口
4),applicationContext的实现类
3.IOC操作Bean治理(基于xml)
1),什么是bean治理:
A,bean治理包含两个步骤:Spring创建对象和Spring属性注入
2),bean治理的实现形式:
a,基于xml配置文件的实现形式
1.基于XML形式创建对象
id属性:给class类门路取个别名
class属性:创建对象类的全门路
XML形式创立默认对象默认应用空参结构器
2.基于XML形式的属性注入
(1),DI:依赖注入,就是注入属性。
DI与IOC的区别:DI是IOC的一种实现。
形式一:应用set形式注入
(a),创立类的对象,创立set办法
(b),在配置文件中配置对象创立,配置属性注入
形式二:应用有参构造方法注入
形式三:p名称空间注入:
第一步:
第二步:
3.注入空值和特殊字符
一,注入空值
二,注入特殊符号
4,注入bean
1),注入内部bean
引入内部bean,用service调用Dao层,就是引入内部bean的过程。
2)注入外部bean 和 级联赋值
级联赋值形式1:不须要dept的get办法。
级联赋值形式2:第二种办法须要创立dept的get办法。
5.注入汇合属性
0),创立Stu类,User类
package com.yuge;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Stu {
//数组类型
private String course[];
//List类型
private List<String> name;
//Map类型
private Map<String,String> map;
//Set类型
private Set<String> set;
//List类型中存入多个对象
private List<User> userList;
public void setUserList(List<User> userList) {
this.userList = userList;
}
public void setCourse(String[] course) {
this.course = course;
}
public void setName(List<String> name) {
this.name = name;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void show(){
System.out.println(Arrays.toString(course));
System.out.println(name);
System.out.println(map);
System.out.println(set);
System.out.println(userList);
}
}
package com.yuge;
public class User {
private String name;
public void setName(String name) {
this.name = name;
}
public void add(){
System.out.println("add.......");
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
1).XML注入数组类型属性
2),XML注入List汇合属性
3),XML注入Map汇合属性
4),XML注入Map属性
5),在汇合中注入对象属性:
<?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:m="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置Stu对象创立-->
<bean id="stu" class="com.yuge.Stu">
<!--注入数组属性-->
<property name="course">
<array>
<value>javaSe</value>
<value>Mysql</value>
</array>
</property>
<!--注入List对象-->
<property name="name">
<list>
<value>武巴</value>
<value>巴巴</value>
</list>
</property>
<!--注入Map对象-->
<property name="map">
<map>
<entry key="JAVASE" value="javase"></entry>
<entry key="SPRING" value="Spring"></entry>
</map>
</property>
<!--注入Set对象-->
<property name="set">
<set>
<value>张三</value>
<value>小三</value>
</set>
</property>
<!--在list中注入对象属性-->
<property name="userList">
<list>
<ref bean="user1"></ref>
<bean id="user1=2" class="com.yuge.User">
<property name="name" value="李华"></property>
</bean>
</list>
</property>
</bean>
<bean id="user1" class="com.yuge.User">
<property name="name" value="李烨"></property>
</bean>
</beans>
6),创立测试类
package com.yuge.test;
import com.yuge.Stu;
import com.yuge.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.applet.AppletContext;
public class Tset {
@Test
public void testAdd(){
//加载配置文件
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("bean2.xml");
//创建对象
Stu stu = (Stu) applicationContext.getBean("stu");
stu.show();
}
}
7),输入后果
8).将汇合向上抽取为所有bean的公共汇合
第一步:引入新的名称空间:
第二步:应用util标签实现list汇合注入的向上抽取
创立新的Book类测试向上抽取注入list
package com.yuge;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import java.util.List;
public class Book {
private List<String> bookList;
public void setBookList(List<String> bookList) {
this.bookList = bookList;
}
public void test(){
System.out.println(bookList);
}
}
配置XML文件抽取注入list的办法:
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<util:list id="list">
<value>java从入门到入土</value>
<value>python从入门到入狱</value>
</util:list>
<bean id="book" class="com.yuge.Book">
<property name="bookList" ref="list"></property>
</bean>
</beans>
运行后果:抽取胜利
抽取之前的样子:
抽取之后的样子:
还能够抽取更多的对象。
6,Spring中的两种bean
1)一般bean:XML中定义什么类型就返回什么类型
2),工厂bean:XML中定义一个类型,能够返回其余类型
第一步:创立类作为工厂bean,实现FactoryBean的接口
第二步:实现接口里的办法,在实现的办法中定义返回的bean类型
package com.yuge.factoryBean;
import com.yuge.Stu;
import org.springframework.beans.factory.FactoryBean;
public class Mybean implements FactoryBean<Stu> {
@Override
public Stu getObject() throws Exception {
Stu stu = new Stu();
return stu;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
第三步:配置XML文件
<bean id="myBean" class="com.yuge.factoryBean.Mybean">
</bean>
测试:
@Test
public void testMyBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
Stu stu = context.getBean("myBean",Stu.class);
System.out.println(stu);
}
后果:
7,bean的作用域:
在XML中配置bean时单实例还是多实例:
8,XML的主动拆卸
主动拆卸:依据指定的拆卸规定,(属性名称或者属性类型),Spring主动将匹配的属性值填入。
演示主动主动拆卸:
1,依据名称拆卸
2,依据属性类型拆卸
9,引入内部属性治理
4.IOC操作Bean(基于注解)
1,spring针对创建对象提供的注解
第一步引入依赖:
第二步:开启组件扫描
第三步:创立类,在类上增加上注解。
1,@Component,都能够应用改注解创建对象
2,@Service,个别用于业务逻辑层,或者service层
3,@Controller,个别用于Web层
4,@Repository,个别用于Dao层
下面的资格注解,性能都一样,只是将每个注解用于不同层便于开发人员区别。
2,开启组件扫面配置的细节配置
3,应用注解出入属性
1),@Autowired:依据属性类型主动注入
第一步:应用注解在各个类中创建对象。
第二步:定义对象属性。在属性下面增加注解。不须要set办法。
2),@Qualifier:依据属性名注入
3),@Resource:能够依据属性名和属性类型注入
以上三种是注入对象,不是一般类型*
4),@Value:注入一般类型
4,齐全注解开发
1),创立配置类,代替XML配置文件
2),编写测试类
三,Aop
面向切面,不批改源码对性能进行增强。
1,什么是AOP
对业务的各个逻辑进行隔离,从而使业务之间的逻辑耦合性升高,进步代码的可重用性,进步开发效率。
2,AOP的底层原理
1,AOP底层应用动静代理
1,有接口的动静代理,应用JDK的动静代理
创立接口的实现类的代理对象,加强类的办法
2,无接口的动静代理,应用CGLIB动静代理
创立子类的代理对象,加强类的办法
2,应用JDK的动静代理
应用proxy类实现动静代理
代码实现:
1,创立接口:
package com.JDK动静代理;
public interface UserDao {
public int add(int a,int b);
public String update(String id);
}
2,创立实现类
package com.JDK动静代理;
public class UserDaoImpl implements UserDao{
@Override
public int add(int a, int b) {
return a+b;
}
@Override
public String update(String id) {
return id;
}
}
3,应用proxy类创立接口的动静代理对象
package com.JDK动静代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.PublicKey;
import java.security.UnresolvedPermission;
import java.util.Arrays;
public class JDKProxy {
public static void main(String[] args) {
Class[] interfaces = {UserDao.class};
UserDao dao = (UserDao)Proxy.newProxyInstance(UserDaoProxy.class.getClassLoader(), interfaces, new UserDaoProxy(new UserDaoImpl()));
int res = dao.add(1, 2);
System.out.println(res);
}
}
class UserDaoProxy implements InvocationHandler{
//须要将待加强性能的类的对象传递到代理类中,并通过构造方法,代理类的构造方法将其实例化
//通过UserDaoProxy创立UserDaoImpl的代理对象
private Object obj;
public UserDaoProxy(Object obj){
this.obj = obj;
}
@Override
/**
*减少逻辑写在这个办法内
* @ proxy:代理对象
* @ method:须要加强的办法
* @ args:要加强性能的办法须要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//办法之前
System.out.println("办法之前执行。。。"+method.getName()+"传递的参数:"+ Arrays.toString(args));
//被加强办法执行
Object res = method.invoke(obj, args);
//办法之后执行
System.out.println("办法之后执行。。。"+obj);
return res;
}
}
3,AOP中的相干术语
1,连接点:那些办法能够被加强,那些办法就叫连接点。
2,切入点:世界真正被加强的办法就叫切入点。
3,告诉(加强):理论被加强的逻辑局部就叫告诉或者加强。
告诉有多种类型:
4,切面:把告诉利用到切入点的动作就叫做切面
## 4,AOP的操作筹备
1,Spring框架个别都是基于AspectJ实现AOP操作
AspectJ:不是Spring框架的一部分,独立于AOP的框架,个别将Spring和AOP框架一起应用进行AOP操作。
2,基于AspectJ实现AOP操作
(1),基于XML配置文件的AOP操作
(2),基于注解形式实现(应用)
3,在我的项目的过程中,引入AOP相干的依赖。
4,切入点表达式
(1),切入点表达式作用:晓得对哪个类外面的那个办法进行加强。
(2),语法结构:
execution:([权限修饰符][返回类型][类全门路][办法名称](参数列表))
举例1:execution(* (返回值能够省略)com.yuge.UserDaoImpl.add(..));
增强com.yuge.UserDaoImpl的add()办法,传入的参数用..示意,权限修饰符用*,返回值类型省略。
举例2:execution( (返回值能够省略)com.yuge.UserDaoImpl.(..)); 对类中的所有办法增强。
举例3:execution( (返回值能够省略)com.yuge..*(..)); 对包中所有类的所有办法增强
5,AOP操作(AspectJ注解)
1,创立一个类,在类中定义方法,应用注解在类中加强该办法。
package com.AOP注解形式;
public class User {
public void add(){
System.out.println("add...................");
}
}
2,创立一个加强类,编写加强逻辑
package com.AOP注解形式;
//加强类
public class UserProxy {
//前置告诉
public void before(){
System.out.println("before.............");
}
}
3,进行告诉的配置
(0)、引入名称空间
(1),在spring的配置文件中,开启注解扫描
<!--开启注解扫描-->
<context:component-scan base-package="com.AOP注解形式"></context:component-scan>
(2),应用注解创立User对象和UserProxy对象。
(3),在加强类下面增加@Aspect注解
(4),在spring配置文件中开启生成代理对象。
<!–开启AspectJ生成代理对象–>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
(5),配置不同类型 的告诉
a,在加强类办法下面,增加告诉类型。应用切入点表达式配置
package com.AOP注解形式;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
//加强类
@Component
@Aspect //生成代理对象
public class UserProxy {
//前置告诉,增加了Before注解,则就会在add()办法之前执行before办法。
@Before("execution(* com.AOP注解形式.User.add(..))")
public void before(){
System.out.println("before.............");
}
//在办法执行之后执行
@After("execution(* com.AOP注解形式.User.add(..))")
public void after(){
System.out.println("after.............");
}
//在办法存在异样时执行
@AfterThrowing("execution(* com.AOP注解形式.User.add(..))")
public void afterThrowing(){
System.out.println("afterThrowing.............");
}
//在办法返回之后执行
@AfterReturning("execution(* com.AOP注解形式.User.add(..))")
public void afterReturning(){
System.out.println("afterReturning.............");
}
//增加盘绕办法,在办法执行前后都执行
@Around("execution(* com.AOP注解形式.User.add(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("盘绕之前.............");
//被加强的办法执行
proceedingJoinPoint.proceed();
System.out.println("盘绕之后..............");
}
}
package com.AOP注解形式;
import org.springframework.stereotype.Component;
@Component
public class User {
public void add(){
System.out.println("add...................");
}
}
package com.AOP注解形式;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void testAdd(){
//加载上下文配置,读取xml配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
//获取对象
User user = (User)context.getBean("user");
user.add();
}
}
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
">
<!--开启注解扫描-->
<context:component-scan base-package="com.AOP注解形式"></context:component-scan>
<!--开启AspectJ生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="user" class="com.AOP注解形式.User"></bean>
</beans>
运行后果:
b,总结:
after无论是否存在异样都会执行,afterReturning存在异样时不会执行。
6,AOP操作(AspextJ注解)优化
1,提取雷同的切入点
//抽取雷同的切入点
@Pointcut(value = "execution(* com.AOP注解形式.User.add(..))")
public void pointCut(){
}
//前置告诉,增加了Before注解,则就会在add()办法之前执行before办法。
@Before("pointCut()")
public void before(){
System.out.println("before.............");
}
//在办法执行之后执行
@After("execution(* com.AOP注解形式.User.add(..))")
public void after(){
System.out.println("after.............");
}
2,当有多个加强类对同一个办法进行加强时,设置加强类优先级
在多个加强类下面设置优先级应用@Order(整型值)这个注解,整型值越小,优先级越高
//加强类
@Component
@Aspect //生成代理对象
@Order(3)
public class UserProxy {
//抽取雷同的切入点
@Pointcut(value = "execution(* com.AOP注解形式.User.add(..))")
public void pointCut(){
}
@Component
@Aspect
@Order(0)
public class UserProxy2 {
@Before("execution(* com.AOP注解形式.User.add(..))")
public void before(){
System.out.println("UserProxy2加强类先执行。。。。。");
}
}
7,AOP操作(XML配置文件)
前提在xml中创立加强类和被加强类的对象
8,齐全注解开发
四,JdbcTemplate
1,JdbcTempalte的概念
Spring对JDBC进行封装,应用JdbcTemplate能够不便的对数据库的操作。
筹备工作:
引入依赖:
配置XML创立类注入属性
2,应用JdbcTemplate模板对数据库的增删改查
<context:component-scan base-package="com"/>
<bean id = "dataSource" class="com.druid.DruidDataSource" destroy-method="close">
<property name="url" value="jdbc:mysql://localhost:3306/jdbc_db"/>
<property name="username" value="root"/>
<property name="password" value="3.141592654"/>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource对象-->
<property name="dataSource" ref="dataSource"></property>
</bean>
public interface BookDao {
void add(Book book);
}
@Repository
public class BookDaoImpl implements BookDao {
//注入JdbcTemplate对象
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void add(Book book) {
String sql = "insert into book values(?,?,?)";
int update = jdbcTemplate.update(sql, book.getId(), book.getName(), book.getPrice());
System.out.println(update);
}
}
@Service
public class BookService {
//注入BookDao属性
@Autowired
private BookDao bookDao;
public void insert(Book book){
bookDao.add(book);
}
}
package com.druid;
public class DruidDataSource {
String url;
String password;
String username;
String driverClassName;
public void setUrl(String url) {
this.url = url;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
private void close() {
}
}
package com.test;
import com.bean.Book;
import com.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestJdbcTemplate {
@Test
public void test(){
ApplicationContext context =
new ClassPathXmlApplicationContext("bean4.xml");
BookService bookService = context.getBean("bookService", BookService.class);
Book book = new Book();
book.setId(1);
book.setName("一阳指");
book.setPrice(250);
bookService.insert(book);
}
}
查问返回某一个值
查问返回某一个对象
查问返回一个汇合
## 3,应用JdbcTemplate模板对数据库的批量操作
五,事务操作
1,事务的概念:
回顾:事务是指一组根本的数据操作单元,要么全副实现操作,要么全副都不实现操作。
典型事务场景:银行转账
事务的四大个性(ACID):原子性,一致性,隔离性,持久性
2,事务环境的搭建
3,spring事务管理的介绍
1,事务增加到JavaEE的三层体系结构的Service层(业务逻辑层)
2,在Spring事务操作:
1),有两种形式:编程式(在办法中增加代码)和申明式(基于XML或者基于注解形式)
2),申明式事务管理:底层应用到AOP
3),Spring事务管理相干的API
4,多事务之间事务的流传行为:
5, ioslation对于事务的隔离级别:
事务的隔离性:多事务的操作之间不会相互影响
如果不思考隔离:会导致脏读,幻读,不可反复读的问题
解决隔离级别:
配置隔离级别:
6,对于事务的超时限度:
7,readOnly是否只读:
8,rollbackFor:回滚
9,noRollbackFor:不回滚
发表回复