文章目录
- Spring 5 框架—入门
- 1 IOC
- 1.1 IOC 是什么
- 1.2 IOC 底层原理
- 1.3 IOC 接口
- 1.4 IOC 操作 Bean 管理
- 1.4.3 IOC 操作 Bean管理(基于 XML 方式)
- 1.4.3.1 基于 XML 方式创建对象
- 1.4.3.2 基于 XML 方式注入属性
- 1.4.3.3 字面量
- 1.4.3.4 注入属性-外部 bean
- 1.4.3.5 注入属性-内部 bean 和级联赋值
- 1.4.3.6 注入属性 - 级联赋值
- 1.4.3.7 IOC操作 Bean 管理 (xml 注入集合属性)
- 1.4.3.8 IOC 操作 Bean 管理 (FactoryBean)
- 1.4.3.9 IOC 操作 Bean 管理 (bean 作用域)
- 1.4.3.10 IOC 操作 Bean 管理 (bean 生命周期)
- 1.4.3.11 IOC 操作 Bean 管理(自动装配)
- 1.4.3.12 IOC 操作 Bean 管理 (外部属性文件)
- 1.4.4 IOC 操作 Bean 管理(基于注解方式)
- 2 AOP
- 3 JDBCTemplate
- SpringMvc
Spring 5 框架—入门
1 IOC
1.1 IOC 是什么
- 控制反转,把对系那个创建和对象间的调用过程,交给 Spring 进行管理。
- 使用ICO目的是为了降低耦合度
1.2 IOC 底层原理
- xml 解析,反射,工厂原理
- 底层原理图
1.3 IOC 接口
-
IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
-
Spring 提供 IOC 容器实现的两种方式 (两个接口)
- BeanFactory :IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用。
- 加载配置文件时,不会创建对象,但在获取对象或者在使用对象才回去创建对象。
- ApplicationContext : BeanFactory 接口是子接口,提供更对更强大的功能,一般由开发人员进行使用。
- 加载配置文件时,就会把在配置文件的对象进行创建对象。
- BeanFactory :IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用。
-
ApplicationContext 接口 实现类
-
BeanFactory 接口 实现类
1.4 IOC 操作 Bean 管理
什么是 Bean 管理
Bean 管理的两个操作
- Spring 创建对象
- Spring 注入属性
Bean 管理操作有两种方式
- 基于 XML 配置文件方式实现
- 基于注解方式实现
1.4.3 IOC 操作 Bean管理(基于 XML 方式)
1.4.3.1 基于 XML 方式创建对象
- 在 Spring 配置文件中,使用 bean 标签,标签里面添加对应属性,就可以实现对象创建。
- 在 bean 标签有很多属性,常用属性:
- id 属性 : 唯一标识
- class 属性: 类全路径(包类路径)
- name 属性:与 id 属性相似,但 name 属性中可以加特殊符号,而 id属性不允许
- 创建对象的时候,默认执行无参构造方法创建对象
1.4.3.2 基于 XML 方式注入属性
-
DI:依赖注入,注入属性
- 第一种注入方式 : setter() 方法
java
- @Description: setter() 方法属性注入
*/
public class Book {
//创建属性
private String Bneam;
private String Bauthor;
//setter() 方法
public void setBauthor(String bauthor) {
Bauthor = bauthor;
}
public void setBneam(String bneam) {
Bneam = bneam;
}
<bean id="book" class="com.atguigu.spring5.Book"> <!--使用property完成属性注入 name: 类属性名称 vaule: 向属性注入的值 --> <property name="bneam" value="易筋经"></property> <property name="bauthor" value="达摩祖师"></property> </bean>
2. 第二种注入方式:有参构造注入
java
* @Description: 使用有参数构造方法进行属性注入
*/
public class Orders {
private String oname;
private String address;
//有参构造
public Orders(String oname, String address) {
this.oname = oname;
this.address = address;
}
public void ordersTest(){
System.out.println(oname+“::”+address);
}
}
3. p 名称空间注入
使用 P 明后才能空间注入,可以简化 xml 配置方式
(1)第一步: 添加 p 名称空间在配置文件中
(2)第二步 :进行属性注入,在 bean 标签中操作 java <!--p 名称空间注入--> <bean id="book" class="com.atguigu.spring5.Book" p:bneam="九阳神功" p:bauthor="无名氏"> </bean>
- 第一种注入方式 : setter() 方法
1.4.3.3 字面量
- null值
-
属性中有特殊符号
1.4.3.4 注入属性-外部 bean
- 创建两个类 service 类和 dao 类
- 在 service 调用 dao 里面的方法
- 在 spring配置文件中进行配置
//创建 UserDao类型的属性,生成set方法
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public void add(){
System.out.println("service add() ...");
userDao.update();
}
//bean2.xml
<!--1.service 和 dao 对象创建-->
<bean id="userService" class="com.atguigu.spring5.service.UserService">
<!-- 注入 userDao 对象
name 属性:类里面的名称
ref 属性:创建 UserDao 对象 bean 标签 id 值
-->
<property name="userDao" ref="userDaoimpl"></property>
</bean>
<bean id="userDaoimpl" class="com.atguigu.spring5.dao.UserDaoimpl">
1.4.3.5 注入属性-内部 bean 和级联赋值
- 一对多关系:部门和员工(一个部门有多个员工,一个员工只属于某一个部门)
- 在实体类之间表示一对多关系,员工表示所属部门,适用对象类型属性进行表示
//部门类
public class Dept {
private String dnema;
public Dept(String dnema) {
this.dnema = dnema;
}
}
//员工类
public class Emp {
private String ename;
private String gender;
private Dept dept; //员工属于某一个部门
public void setDept(Dept dept) {
this.dept = dept;
}
public void setEname(String ename) {
this.ename = ename;
}
public void setGender(String gender) {
this.gender = gender;
}
}
- 在Spring配置文件中进行配置
<!--内部bean-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<!--设置两个基础属性-->
<property name="ename" value="lucy"></property>
<property name="gender" value="女"></property>
<!--设置对系那个类型属性-->
<property name="dept">
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value="安保部"></property>
</bean>
</property>
</bean>
1.4.3.6 注入属性 - 级联赋值
<!--第一种 级联赋值-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<!--设置两个基础属性-->
<property name="ename" value="lucy"></property>
<property name="gender" value="女"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value="财务部"></property>
</bean>
<!--第二种 级联赋值-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
<!--设置两个基础属性-->
<property name="ename" value="lucy"></property>
<property name="gender" value="女"></property>
<!--级联赋值-->
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="技术部">
<!--需要在emp中生成getDept()方法-->
</property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
<property name="dname" value="财务部"></property>
1.4.3.7 IOC操作 Bean 管理 (xml 注入集合属性)
-
注入数组类型属性
-
注入 List 集合类型属性
-
注入 Map 集合类型属性
public class Stu { //数组类型 private String[] courses; // List 集合类型属性 private List<String> list ; //map 集合类型属性 private Map<String,String> maps; // Set 集合类型属性 private Set<String> sets; public void setCourses(String[] courses) { this.courses = courses; } public void setSets(Set<String> sets) { this.sets = sets; } public void setList(List<String> list) { this.list = list; } public void setMaps(Map<String, String> maps) { this.maps = maps; } }
4. 在 Spring 配置文件中进行配置 ```xml <!--1.集合类型属性注入--> <bean id="stu" class="com.atguiogu.spring5.collectiontype.Stu"> <!--数组类型属性注入--> <property name="courses"> <array> <value>java</value> <value>sql</value> </array> </property> <!--list类型属性注入--> <property name="list"> <list> <value>张三</value> <value>小三</value> </list> </property> <!--Map 类型属性注入--> <property name="maps"> <map> <entry key="JAVA" value="java"></entry> <entry key="PHP" value="php"></entry> </map> </property> <!--set类型属性注入--> <property name="sets"> <set> <value>java</value> <value>php</value> </set> </property> </bean> ``` 5. 在集合中设置对象类型值 ```xml <!--注入list集合类型,值是对象--> <property name="courseList"> <list> <ref bean="course1"></ref> <ref bean="course2"></ref> </list> </property> <!--创建多个course对象--> <bean id="course1" class="com.atguiogu.spring5.collectiontype.Course"> <property name="cname" value="Spring5 框架"></property> </bean> <bean id="course2" class="com.atguiogu.spring5.collectiontype.Course"> <property name="cname" value="MyBatis 框架"></property> </bean> ``` 6. 把集合注入部分提取出来 1. 在 spring 配置文件中引入名称空间 util ```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" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" 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"> ``` 2. 使用 util 标签完成 list 集合注入提取 ```xml <!--1.提取list集合类型属性注入--> <util:list id="booklist"> <value>易筋经</value> <value>九阴真经</value> <value>九阳神功</value> </util:list> <!--1.提取list集合类型属性注入使用--> <bean id="book" class="com.atguiogu.spring5.collectiontype.Book"> <property name="list" ref="booklist"></property> </bean> ```
1.4.3.8 IOC 操作 Bean 管理 (FactoryBean)
-
Spring 有两种 Bean ,一种是普通 Bean,另一种是工程 Bean (FactoryBean)
-
普通 bean: 在配置文件中定义的 Bean 类型就是返回类型
-
工厂 bean: 在配置文件中定义 bean 类型可以和返回类型不一样
-
创建类,让该类作为工厂 bean,实现接口 FactoryBean
-
实现接口里面的方法,在实现的方法中定义返回的 bean 类型
public class MyBean implements FactoryBean { //定义返回 bean @Override public Object getObject() throws Exception { Course course = new Course(); course.setCname("abc"); return course; } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } } @Test public void testFactoryBean(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Course myBean1 = context.getBean("myBean", Course.class); System.out.println(myBean1); } //bean3.xml <bean id="myBean" class="com.atguiogu.spring5.collectiontype.factorybean.MyBean"></bean>
-
1.4.3.9 IOC 操作 Bean 管理 (bean 作用域)
-
在 Spring 中,设置创建 Bean 实例是单实例还是多实例
-
在 Spring 中,默认情况下创建单实例对象
-
设置但实力还是多实例
-
在 Spring 配置文件 bean 标签里面有属性 (scope) 用于设置但实力还是多实例
-
scope 属性值
第一个值 默认值 singleton 表示单实例对象
第二个值 prototype 表示多实例对象
还有 request session .
-
singleton 和 prototype 区别
1. singleton 单实例 prototype 多实例
2. 设置 scope 值是 singleton 时,加载 Spring 配置文件时就会创建单实例对象; 设置 scope 值为 prototype 时,不是在加载 Spring 配置文件时创建对象,而是在调用 getBean 方法时,创建多实例对象。
![image-20220427230852479](https://i-blog.csdnimg.cn/blog_migrate/eeb053a68f013f03e8ce93c672e55de9.png)
1.4.3.10 IOC 操作 Bean 管理 (bean 生命周期)
-
生命周期:从对象创建到对象销毁的过程
-
bean 生命周期
-
通过构造器创建 bean 实例(无参构造)
-
为 bean 的属性设置值和对其他 bean 引用 (调用 set 方法)
-
将 bean 是传递 bean后置处理器的方法
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; }
-
调用 bean 的初始化的方法 (需要进行配置初始化的方法)
-
把 bean 实例传递 bean 后置处理器的方法
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
-
bean 可以使用了(对象获取到了)
-
当容器关闭时,调用 bean 的销毁的方法 (需要进行配置销毁的方法)
-
-
演示 bean生命周期
bean4.xml <bean id="orders" class="com.atguiogu.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod"> <property name="oname" value="手机"></property> </bean> public class Orders { private String oname; public void setOname(String oname) { this.oname = oname; System.out.println("2. 调用set方法设置属性值"); } // 无参构造 public Orders() { System.out.println("1. Orders 无参数构造"); } // 创建执行的初始化的方法 public void initMethod(){ System.out.println("3. 执行初始化的方法"); } // 创建销毁方法 public void destroyMethod(){ System.out.println("5. 执行销毁的方法"); } } @Test public void testBean(){ ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Orders orders = context.getBean("orders", Orders.class); System.out.println("4. 获取创建的 bean 实例对象"); System.out.println(orders); //手动让 bean 实例销毁 ((ClassPathXmlApplicationContext)context).close(); } // 运行结果:未添加后置处理器 1. Orders 无参数构造 2. 调用set方法设置属性值 3. 执行初始化的方法 4. 获取创建的 bean 实例对象 com.atguiogu.spring5.bean.Orders@4524411f 5. 执行销毁的方法
-
Bean生命周期 – 添加后置处理器效果
- 创建类,实现接口 BeanPostProcessor,创建后置处理器
public class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之前执行"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之后执行"); return bean; } } //bean4.xml <bean id="orders" class="com.atguiogu.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod"> <property name="oname" value="手机"></property> </bean> <!--配置后置处理器--> <bean id="MyBeanPost" class="com.atguiogu.spring5.bean.MyBeanPost"></bean> //运行结果 添加后置处理器 1. Orders 无参数构造 2. 调用set方法设置属性值 在初始化之前执行 3. 执行初始化的方法 在初始化之后执行 4. 获取创建的 bean 实例对象 com.atguiogu.spring5.bean.Orders@704d6e83 5. 执行销毁的方法
1.4.3.11 IOC 操作 Bean 管理(自动装配)
-
自动装配:根据指定装配规则 (属性名称或者属性类型),Spring 自动将匹配的属性值进行注入
-
自动装配过程
<!--手动装配--> <!-- <bean id="emp" class="com.atguiogu.spring5.autowire.Emp">--> <!-- <property name="dept" ref="dept"></property>--> <!-- </bean>--> <!-- <bean id="dept" class="com.atguiogu.spring5.autowire.Dept"></bean>--> <!--自动装配--> <bean id="emp" class="com.atguiogu.spring5.autowire.Emp" autowire="byName"> <!-- bean 标签属性 autowire ,自动装配 autowire 属性常用两个值: byName 根据属性名成注入 注入值 bean的id值与类属性名称一样 byType 根据属性类型注入 --> </bean> <bean id="dept" class="com.atguiogu.spring5.autowire.Dept"></bean> </beans>
public class Dept { @Override public String toString() { return "Dept{}"; } } public class Emp { private Dept dept; public void setDept(Dept dept) { this.dept = dept; } @Override public String toString() { return "Emp{" + "dept='" + dept + '\'' + '}'; } public void test(){ System.out.println(dept); } }
1.4.3.12 IOC 操作 Bean 管理 (外部属性文件)
-
直接配置数据库信息
-
配置德鲁伊连接池
-
引入德鲁伊连接池依赖 jar 包
-
在配置文件中配置数据库信息
<!--直接配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!--获取property文件内容,根据key获取,使用spring表达式获取--> <!-- <property name="driverClassName" value="${jdbc.driverclass}"></property>--> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <!-- <property name="url" value="${jdbc.url}"></property>--> <property name="url" value="jdbc:mysql://localhost:3306/hsp_db02"></property> <!-- <property name="username" value="${jdbc.username}"></property>--> <property name="username" value="lxj"></property> <!-- <property name="password" value="${jdbc.password}"></property>--> <property name="password" value="lxj"></property> </bean>
-
-
引入外部属性文件配置数据库连接池
-
创建外部属性文件,properties 格式文件,写数据库信息
prop.driverClass=xom.mysql.cj.jdbc.Driver prop.url=jdbc:mysql://localhost:3306/hsp_db02 prop.userName=lxj prop.password=lxj
-
将外部 properties 属性文件引入 spring 配置文件
- 引入 context 名称空间
```xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> ```
-
在 spring 配置文件中使用标签引入外部属性文件
<!--引入外部属性文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--直接配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!--获取property文件内容,根据key获取,使用spring表达式获取--> <property name="driverClassName" value="${prop.driverclass}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.userName}"></property> <property name="password" value="${prop.password}"></property> </bean>
-
1.4.4 IOC 操作 Bean 管理(基于注解方式)
-
什么是注解
- 注解是代码中特殊标记。格式:@注解名称(属性名称=属性值,属性名称=属性值 …)
- 使用注解,注解可以作用于类,方法,属性
- 注解的目的:简化 xml 配置
-
Spring 针对 Bean 管理中创建对象提供的注解
-
@Component
-
@Service
-
@Controller
-
@Repository
-
以上四个注解功能是一样的,都可以创建 bean 实例
-
1.4.4.1 基于注解方式实现对象创建
-
引入依赖 (aop jar 包)
-
开启组件扫描
<?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" 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"> <!--开组件扫描 1. 扫描多个包,多个包使用逗号隔开 <context:component-scan base-package="com.atguiogu.spring5.dao,com.atguiogu.spring5.service"></context:component-scan> 2. 扫描包的上层目录 --> <context:component-scan base-package="com.atguiogu.spring5"></context:component-scan> </beans>
-
创建类,在类上添加创建对象的注解
@Component(value = "userService") //<bean id ="userService" class="..."/> // 在注解里面value属性值可以省略不写, // 默认值是类名称,首字母小写 UserService -- userService public class UserService { public void add(){ System.out.println("service add ... "); } } public class TestDemo { @Test public void testService() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); } com.atguiogu.spring5.service.UserService@60dcc9fe service add ...
-
开启组件扫描细节配置
<!--示例1 use-default-filters="false" 表示不使用默认 filter,自己配置 filter context:include-filter 设置扫描哪些内容 --> <context:component-scan base-package="com.atguiogu.spring5" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--实例2 以下配置扫描包中所有内容 context:exclude-filter: 设置哪些内容不进行扫描 --> <context:component-scan base-package="com.atguiogu.spring5" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
1.4.4.2 基于注解方式实现属性注入
-
@AutoWired:根据属性类型进行自动装配
-
创建 service 和 dao 对象创建,在service和dao类添加创建对象注解
-
在 service 注入 dao 对象,在 service 类中添加 dao 类型属性
public class UserService { @Autowired // 定义dao对象,不需要set方法 添加注入属性注解 private UserDao userDao; public void add(){ System.out.println("service add ... "); userDao.add(); } } @Test public void testService() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); } com.atguiogu.spring5.service.UserService@60dcc9fe service add ... dao add ...
-
-
@Qualifier:根据属性名称进行注入
-
@Qualifier 注解使用要和 @AutoWired 一起使用
public class UserService { @Autowired @Qualifier(value = "userDaoImp1")//根据名称进行注入 // 定义dao对象,不需要set方法 添加注入属性注解 private UserDao userDao; public void add(){ System.out.println("service add ... "); userDao.add(); } }
-
-
@Resource:可以根据属性类型注入,也可以根据属性名称注入
//@Resource //根据类型注入 @Resource(name = "userDaoImp1")//根据名称注入 private UserDao userDao;
-
@Value:注入普通类型属性
@Value(value="abc") private String name;//普通类型属性
1.4.4.3 完全注解开发
-
创建配置类,替代 xml 配置文件
@Configuration //作为配置类,替代 xml 配置文件 @ComponentScan(basePackages = {"com.atguigu" }) public class SpringConfig { }
-
编写测试类
@Test public void testService02() { //加载配置类 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); UserService userService = context.getBean("userService", UserService.class); System.out.println(userService); userService.add(); }
2 AOP
2.1 AOP 介绍
- AOP: 面向切面(方面)编程
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。(不修改源代码方式,在主干功能里面添加新功能)
2.2 AOP 底层原理
-
底层使用 动态代理
-
有接口动态代理,JDK 动态代理
创建接口实现类代理对象,增强类的方法
-
无接口动态代理,CGLIB 动态代理
创建子类的代理对象,增强类的方法
-
2.2.1 JDK 动态代理
-
使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
- 调用 NewProxyInstance 方法
- 第一个参数: 类加载器
- 第二个参数:增强方法所在的类,该类实现的接口,支持多接口
- 第三个参数:实现该接口 InvocationHandler,创建代理对象,写增强方法
- 调用 NewProxyInstance 方法
-
JDK动态代理
-
创建接口,定义方法
public interface UserDao { public int add(int a, int b); public String update(String id); }
-
创建接口实现类,实现方法
public class UserDaoImpl implements UserDao { @Override public int add(int a, int b) { return a+b; } @Override public String update(String id) { return id; } }
-
使用 Proxy 类创建接口代理对象
public class JDKProxy { public static void main(String[] args) { //创建接口实现类的代理对象 方式一 Class[] interfaces = {UserDao.class}; // Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new InvocationHandler() { // @Override // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // return null; // } // }); //方式二 UserDaoImpl userDao = new UserDaoImpl(); UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); int add = dao.add(1, 2); System.out.println("add="+add); } } //创建代理对象代码 class UserDaoProxy implements InvocationHandler{ //1.将创建的是谁的代理对选哪个,把谁传递过来 //有参构造函数 private Object obj ; public UserDaoProxy(Object obj) { this.obj = obj; } // 增强的逻辑 @Override 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; } }
-
2.2.2 AOP 相关术语
-
连接点
类里面哪些方法可以被增强,这些方法称为连接点
-
切入点
实际真正被增强的方法,成为切入点
-
通知(增强)
-
实际增强的逻辑部分称为通知(增强)
-
通知的类型:
- 前置通知
- 后置通知
- 环绕通知
- 异常通知
- 最终通知
-
-
切面
切面是动作,即将通知应用到切入点的过程
2.2.3 AOP 操作准备
-
Spring 框架一般都是基于 AspectJ 实现 AOP 操作
- AspectJ 不是 Spring 组成部分,独立AOP 框架,一般把 ASpectJ 和 Spring 框架一起使用,进行 AOP 操作
-
基于 AspectJ 实现 AOP 操作
-
基于 xml 配置文件实现
-
基于注解方式实现(使用)
-
在项目工程里引入 AOP 相关依赖
-
切入点表达式
-
切入点表达式作用,知道对哪个类里面的哪个方法进行增强
-
语法结构:
-
execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))
-
举例1: 对com.atguigu.dao.BookDao 类里面的 add 进行增强
execution(* com.atguigu.dao.BookDao.add(…))
举例2: 对com.atguigu.dao.BookDao 类里面的所有方法进行增强
execution(* com.atguigu.dao.BookDao.*(…))
举例2: 对com.atguigu.dao 包里所有类里面的所有方法进行增强
execution(* com.atguigu.dao.
*
.*
(…))
-
-
2.2.4 AOP 操作 (AspectJ 注解)
-
创建类,在类里面定义方法
//被增强的类 public class User { public void add(){ System.out.println("add..."); } }
-
创建增强类 (编写增强逻辑)
-
在增强类中,创建方法,让不同的方法代表不同的通知类型
//增强的类 public class UserProxy { //前置通知 public void before(){ System.out.println("before......"); } }
-
-
进行通知配置
-
在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" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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"> <!--开组件扫描 1. 扫描多个包,多个包使用逗号隔开 <context:component-scan base-package="com.atguiogu.spring5.dao,com.atguiogu.spring5.service"></context:component-scan> 2. 扫描包的上层目录 --> <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan> </beans>
-
使用注解创建 User 和 UserProxy 对象
-
在增强类上面添加注解 @Aspect
-
在 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" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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"> <!--开组件扫描 1. 扫描多个包,多个包使用逗号隔开 <context:component-scan base-package="com.atguiogu.spring5.dao,com.atguiogu.spring5.service"></context:component-scan> 2. 扫描包的上层目录 --> <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan> <!--开启AspectJ生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
-
-
配置不同类型的通知
-
在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式
@Component @Aspect //增强的类 public class UserProxy { //前置通知 @Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void before(){ System.out.println("before......"); } //最终通知 @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void after(){ System.out.println("after......方法执行之后执行"); } //异常通知 @AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void AfterThrowing(){ System.out.println("AfterThrowing......"); } //环绕通知 @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕之前......"); //被增强的方法 proceedingJoinPoint.proceed(); System.out.println("环绕之后......"); } // 后置通知 (返回通知) @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void afterReturning(){ System.out.println("AfterReturning......返回值之后执行"); } }
-
-
相同切入点进行抽取
// 相同切入点抽取 @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") public void pointdemo(){ }
-
有多个增强类对同一个方法进行增强,设置增强类的优先级
- 在增强类上添加一个注解@Order(数字类型值),数字类型值越小,优先级越高
-
完全注解开发
@Test public void testAopAnnoEntire() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigAop.class); User user = context.getBean("user", User.class); user.add(); } @Configuration @ComponentScan(basePackages = {"com.atguigu"})//开启注解扫描 @EnableAspectJAutoProxy(proxyTargetClass = true)//开启Aspect生成代理对象 public class ConfigAop { }
2.2.5 AOP 操作 (AspectJ 配置文件)
-
创建两个类,增强类和被增强类,创建方法
-
在 Spring 配置文件中创建两个对象
-
在 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" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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"> <!--创建对象--> <bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean> <bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean> <!--配置aop增强--> <aop:config> <!--切入点配置--> <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..))"/> <!--配置切面--> <aop:aspect ref="bookProxy"> <!--增强作用在具体的方法上--> <aop:before method="before" pointcut-ref="p"></aop:before> </aop:aspect> </aop:config> </beans>
3 JDBCTemplate
3.1 概念和准备
-
什么是 JDBCTempate
- Spring 框架对 JDBC 进行封装,使用 JDBCTemplate 方便实现对数据库操作
-
准备工作
-
引入相关 jar 包
-
在 spring 配置文件中配数据库连接池
-
配置 JdbcTemplate 对象,注入 DataSource
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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"> <!--直接配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!--获取property文件内容,根据key获取,使用spring表达式获取--> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/hsp_db02"></property> <property name="username" value="lxj"></property> <property name="password" value="lxj"></property> </bean> <!--JdbcTempate对象--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!--注入--> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
-
创建 service、dao 类 在 dao 注入 jdbcTemplate 对象
配置文件
<!--开启注解扫描--> <context:component-scan base-package="com.atguigu.spring5"></context:component-scan> <!--直接配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!--获取property文件内容,根据key获取,使用spring表达式获取--> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/hsp_db02"></property> <property name="username" value="lxj"></property> <property name="password" value="lxj"></property> </bean> <!--JdbcTempate对象--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!--注入--> <property name="dataSource" ref="dataSource"></property> </bean>
Service
@Service public class BookService { //注入 dao @Autowired private BookDao bookDao; }
Dao
@Repository public class BookDaoImpl implements BookDao{ //注入jdbc Template @Autowired private JdbcTemplate jdbcTemplate; }
-
3.2 JDBCTemplate 操作数据库
3.2.1 DML 操作
-
对应数据库表创建实体类
-
编写 service 和 dao
-
在 dao 进行数据库添加操作
-
调用 JDBCTemplate 独享里面 update 方法实现添加操作
@Repository public class BookDaoImpl implements BookDao{ //注入jdbc Template @Autowired private JdbcTemplate jdbcTemplate; @Override public void add(Book book) { String sql = "insert into t_book values (?,?,?)"; int update = jdbcTemplate.update(sql, book.getUserId(),book.getUsername(),book.getUstatus()); System.out.println("update = " + update); } }
-
修改删除操作
String sql = "insert into t_book values (?,?,?)"; int update = jdbcTemplate.update(sql, book.getUserId(),book.getUsername(),book.getUstatus()); System.out.println("update = " + update);
-
3.2.2 查询操作
-
查询表里记录数量—单值查询
// 查询表里的记录数量 @Override public void findCount() { String sql = "select count(*) from t_book"; Integer queryCount = jdbcTemplate.queryForObject(sql, Integer.class); System.out.println("queryCount = " + queryCount); }
-
查询返回对象
@Override public void findObject(String id) { String sql = "select * from t_book where userid=?"; /**queryForObject * 第一个参数:SQL语句 * 第二个参数:接口,返回不同类型没使用该接口完成数据封装 * 第三个参数:SQL语句值 */ Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id); System.out.println("book = " + book); }
-
查询返回集合
//查询返回集合 @Override public void findAll() { String sql = "select * from t_book"; List<Book> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class)); for (Book book : query) { System.out.println("book = " + book); } }
3.2.3 批量操作
-
批量操作:操作表里面多条记录
-
批量添加
@Override public void batchAdd(List<Object[]> batchArgs) { String sql = "insert into t_book values(?,?,?)"; /**batchUpdate(sql, batchArgs) * 第一个参数:SQL语句 * 第二个参数:List集合,添加多条记录 */ int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs); System.out.println(Arrays.toString(ints)); } // 批量添加 ArrayList<Object[]> objects = new ArrayList<>(); Object[] o1 ={"3","java","a"}; Object[] o2 ={"4","english","b"}; Object[] o3 ={"5","web","c"}; objects.add(o1); objects.add(o2); objects.add(o3); bookService.batchAdd(objects);
3.2.4 事务
-
事务是数据操作的最基本的单元,逻辑上的一组操作,要么都成功,要么一个操作失败所有操作都失败。
-
事务的四个特性(ACID)
- 原子性
- 一致性
- 隔离性
- 持久性
-
事务操作(搭建实务操作环境)
-
创建数据库和表,添加记录
-
创建 service,搭建 dao 完成对象创建和注入关系
-
service 注入 dao ,在 dao 中注入 JdbcTemplate ,在 JdbcTemplate 注入DataSource 。
@Service public class UserService { @Autowired private UserDao userDao; } public class UserDaoImpl implements UserDao{ @Autowired private JdbcTemplate jdbcTemplate; }
-
-
在 Service 和 Dao 中分别创建转账方法和支付、收款方法 。
// 转账 public void accountMoney(){ userDao.reduceMoney(); userDao.addMoney(); } public interface UserDao { public void addMoney(); public void reduceMoney(); } @Repository public class UserDaoImpl implements UserDao{ @Autowired private JdbcTemplate jdbcTemplate; @Override public void addMoney() { String sql = "update t_account set money = money + ? where username = ?"; int mary = jdbcTemplate.update(sql, 100, "mary"); System.out.println("mary = " + mary); } @Override public void reduceMoney() { String sql = "update t_account set money = money - ? where username = ?"; int lucy = jdbcTemplate.update(sql, 100, "lucy"); System.out.println("lucy = " + lucy); } }
-
事务操作( Spring 事务管理)
-
事务添加到 JavaEE 三层结构的 Service 层(业务逻辑层)
-
在 Spring 进行事务管理操作
- 编程式事务管理 和 声明式事务管理(推荐使用)
-
声明式事务管理
-
基于注解方式(推荐使用)
-
基于 xml 配置文件方式
-
在 Spring 进行声明式事务管理,底层使用 AOP
-
Spring 事务管理 API
-
提供接口,代表事务管理器,正对不同的框架提供了不同的实现类
-
-
-
声明式事务管理
-
在spring配置文件中配置事务管理器
<!--创建事务管理器--> <bean id="transactionMananger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入数据源--> <property name="dataSource" ref="dataSource"></property> </bean>
-
在 spring 配置文件中开启事务注解
-
在 Spring 配置文件 引入名称空间 tx
xmlns:tx="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
-
开启事务注解
<!--开启事务注解--> <tx:annotation-driven transaction-manager="transactionMananger"></tx:annotation-driven>
-
在 service 类上(或者 service 类里面方法上 )添加事务注解 @Transactional
@Transactional //事务注解 // 转账 public void accountMoney() { //1. 开启事务 //2. 进行业务操作 userDao.reduceMoney(); //模拟异常 int i = 100 / 0; userDao.addMoney(); //3. 提交事务 //4. 事务回滚 }
-
-
声明式事务管理参数配置
-
在 service 类或者里面方法上添加@Transactional注解中相关参数
-
propagation: 事务传播行为
多事务方法直接进行调用,该过程事务如何进行管理
-
isolation: 事务隔离级别
-
事务的隔离性,多事务操作之间不会产生影响,不考虑隔离性产生很多问题
-
脏读、不可重复读、虚(幻)读
-
脏读:一个未提交事务读取到另一个未提交事务的数据
-
不可重复读:一个未提交的事务读取到另一个提交事务的修改数据
-
幻读:一个未提交事务读取到另一个提交事务添加数据
-
通过设置事务的隔离性,解决以上问题
-
-
timeout:超时时间
- 事务需要在一定时间内进行提交,若不提交则回滚
- 默认值是-1,设置时间以秒为单位进行计算
-
readOnly:是否只读
- 读: 查询操作,写:添加修改删除操作
- readOnly 默认值 false,表示可读,可写
- 设置 readOnly 置为 true,只能读
-
rollbackFor:回滚
- 设置出现哪些异常进行事务回滚
-
noRollbackFor: 不回滚
- 设置出现哪些异常不进行事务回滚
-
-
-
-
基于 xml 配置文件方式
-
配置事务管理器
-
配置通知
-
配置切入点和切面
<!--开启注解扫描--> <context:component-scan base-package="com.atguigu.spring5"></context:component-scan> <!--直接配置连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!--获取property文件内容,根据key获取,使用spring表达式获取--> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/hsp_db02?"></property> <property name="username" value="lxj"></property> <property name="password" value="lxj"></property> </bean> <!--JdbcTempate对象--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!--注入--> <property name="dataSource" ref="dataSource"></property> </bean> <!--1.配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入数据源--> <property name="dataSource" ref="dataSource"></property> </bean> <!--2.配置通知--> <tx:advice id="txadvice"> <!--配置事务参数--> <tx:attributes> <!--指定哪种规则的方法上面添加事务--> <tx:method name="accountMoney" propagation="REQUIRED"/> <!--<tx:method name="account*" propagation="REQUIRED"></tx:method>--> </tx:attributes> </tx:advice> <!--3.配置切入点和切面--> <aop:config> <!--配置切入点--> <aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/> <!--配置切面--> <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/> </aop:config> </beans>
// 转账 xml配置文件 public void accountMoney() { //1. 开启事务 //2. 进行业务操作 userDao.reduceMoney(); //模拟异常 int i = 100 / 0; userDao.addMoney(); //3. 提交事务 //4. 事务回滚 }
-
-
完全注解开发
@Test public void test03(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class); UserService userService = context.getBean("userService", UserService.class); userService.accountMoneyAnno(); } @Configuration //配置类 @ComponentScan(basePackages = "com.atguigu.spring5" )//注解扫描 @EnableTransactionManagement//开启事务 public class TxConfig { //创建数据库连接池 @Bean public DruidDataSource getDruidDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/hsp_db02"); dataSource.setUsername("lxj"); dataSource.setPassword("lxj"); return dataSource; } // 创建JDBCTemplate 对象 public JdbcTemplate getJdbcTemplate(DataSource dataSource) { // 到 ico 容器中根据数据类型找到 dataSource JdbcTemplate jdbcTemplate = new JdbcTemplate(); //注入dataSource jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; } // 创建事务管理器 @Bean public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }
-
SpringMvc
入门案例
//UserController.java
package com.itheima.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @Author: Max_Li
* @Date: 2022/6/27 20:16
* @Version:
* @Description:
*/
/**
* 1.定义 controller
* 2.使用 @Controller 定义Bean
*/
@Slf4j
@Controller
public class UserController {
//2.2 设置当前操作的访问路径
@RequestMapping("/save")
//2.3 设置当前操作的返回值类型
@ResponseBody
public String save(){
log.info("userController save()...");
return "{'moudule':'springmvc_save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(){
log.info("userController delete()...");
return "{'moudule':'springmvc_delete'}";
}
}
//SpringMvcConfig.java
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Author: Max_Li
* @Date: 2022/6/27 20:04
* @Version:
* @Description:
*/
/**
* 创建 SpringMVC 配置文件,加载 controller 对应的 bean
*/
@Configuration
@ComponentScan({"com.itheima.controller"})
public class SpringMvcConfig {
}
//ServletContainersInitConfig.java
package com.itheima.config;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
/**
* @Author: Max_Li
* @Date: 2022/6/27 20:06
* @Version:
* @Description:
*/
/**
* 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
*/
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载SpringMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置哪些请求归属SpringMVC
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载Spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
//SpringConfig.java
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
/**
* @Author: Max_Li
* @Date: 2022/6/27 20:04
* @Version:
* @Description:
*/
/**
* 创建 SpringMVC 配置文件,加载 controller 对应的 bean
*/
@Configuration
//@ComponentScan({"com.itheima.service","com.itheima.dao"})
@ComponentScan(value={"com.itheima"},
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
//SpringMvcConfig.java
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
/**
* @Author: Max_Li
* @Date: 2022/6/27 20:04
* @Version:
* @Description:
*/
/**
* 创建 SpringMVC 配置文件,加载 controller 对应的 bean
*/
@Configuration
@ComponentScan({"com.itheima.controller"})
public class SpringMvcConfig {
}
//ServletContainersInitConfig.java
package com.itheima.config;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
/**
* @Author: Max_Li
* @Date: 2022/6/27 20:06
* @Version:
* @Description:
*/
/**
* 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
*/
/public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载SpringMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
//加载Spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
//设置哪些请求归属SpringMVC
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}*/
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
本人学习笔记,如有侵权请联系。