SSM
介绍SSM框架<原理>
一、什么是SSM框架?
SSM框架是spring、spring MVC 、和mybatis框架的整合,是标准的MVC模式。标准的SSM框架有四层,分别是dao层(mapper),service层,controller层和View层。使用spring实现业务对象管理,使用spring MVC负责请求的转发和视图管理,mybatis作为数据对象的持久化引擎。
1)持久层:dao层(mapper)层
作用:主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此。
Dao层首先设计的是接口,然后再Spring的配置文件中定义接口的实现类。
然后可以在模块中进行接口的调用来进行数据业务的处理。(不在关心接口的实现类是哪个类)
数据源的配置以及有关数据库连接的参数都在Spring的配置文件中进行配置。
2)业务层:Service层
作用:Service层主要负责业务模块的逻辑应用设计。
先设计接口然后再设计实类,然后再在Spring的配置文件中配置其实现的关联。(业务逻辑层的实现具体要调用到自己已经定义好的Dao的接口上)这样就可以在应用中调用Service接口来进行业务处理。
建立好Dao之后再建立service层,service层又要在controller层之下,因为既要调用Dao层的接口又要提供接口给controller层。每个模型都有一个service接口,每个接口分别封装各自的业务处理的方法。
3)表现层:Controller层(Handler层)
作用:负责具体的业务模块流程的控制。
配置也同样是在Spring的配置文件里面进行,
调用Service层提供的接口来控制业务流程。
业务流程的不同会有不同的控制器,在具体的开发中可以将我们的流程进行抽象的归纳,设计出可以重复利用的子单元流程模块。
创建一个Maven程序
要在 IntelliJ IDEA 中创建一个 Maven Java 程序,请按照以下步骤操作:
-
打开 IntelliJ IDEA,点击欢迎界面上的 “Create New Project” 或者从菜单栏选择 “File -> New -> Project”。
-
在弹出的对话框中,选择 “Maven” 选项,并点击 “Next”。
-
在 “New Project” 对话框中,选择 “Create from archetype”,然后点击 “Add Archetype”。
-
在 “Add Archetype” 对话框中,输入以下信息:
- GroupId:
org.apache.maven.archetypes
- ArtifactId:
maven-archetype-quickstart
- Version:
1.4
- GroupId:
-
点击 “OK” 添加该 Archetype 并返回到 “New Project” 对话框。
-
在 “New Project” 对话框中,可以为项目指定一个 “GroupId” 和 “ArtifactId”,然后点击 “Next”。
- “GroupId” 是项目所属的组织或者包的标识符,例如
com.example
。 - “ArtifactId” 是项目的唯一标识符,例如
myproject
。
- “GroupId” 是项目所属的组织或者包的标识符,例如
-
在 “Project Name” 输入框中,输入项目的名称。
-
确认项目路径并点击 “Finish” 完成项目的创建。
-
IntelliJ IDEA 将会自动为你创建一个 Maven 项目的基本结构。
-
在项目结构中,可以在
src/main/java
目录下创建 Java 源代码文件,并编写你的程序代码。 -
在
pom.xml
文件中配置依赖项和其他项目配置。你可以直接编辑pom.xml
文件进行配置。 -
构建和运行:
- 在 IDEA 的右侧导航栏中,找到 “Maven Projects”(Maven 项目)窗口。
- 展开 “Lifecycle” 并双击 “clean”,然后再双击 “install”,或者右键点击 “install” 并选择 “Run ‘install’” 来构建项目。
-
运行程序:
- 在 IDEA 的顶部菜单栏中,选择 “Run -> Edit Configurations”。
- 点击 “+” 按钮创建一个新的运行配置。
- 选择 “Application” 并配置 “Main Class”、“Program arguments” 和其他必要的参数。
- 点击 “OK” 保存配置。
- 点击 “Run” 按钮运行程序。
以上是在 IntelliJ IDEA 中创建一个 Maven Java 程序的基本步骤。你可以根据自己的需求和项目类型进一步配置和扩展项目。
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: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">
<!-- 注解扫描器配置 -->
<context:component-scan base-package="com.xm.Service.test"></context:component-scan>
<bean id="test2" class="com.xm.Service.test.Test2"></bean>
<!-- 数据源配置 -->
<!--
<context:property-placeholder location="c3p0.properties"></context:property-placeholder>
-->
</beans>
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>app Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--sql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.3</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!--添加以下两个依赖为了渲染前端页面-->
<!-- JSTL -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2-rev-1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Expression Language (EL) -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.xm.Model"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库的连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///sjk1?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql的映射文件-->
<mapper resource="com/xm/dao/Ntable.xml"/>
</mappers>
</configuration>
Mybatis
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace名称空间 单独的sql映射文件 返回结果resultType对应类-->
<mapper namespace="com.xm.dao.Ntable">
<insert id="addNtable">
insert into Ntable (nname,nage,nid)
value (#{nname},#{nage},#{nid});
</insert>
<update id="DeleteNtable">
delete from Ntable
where nid=#{nid};
</update>
<update id="UpdateNtable">
UPDATE Ntable
SET nname = #{nname}, nage = #{nage}
WHERE nid = #{nid};
</update>
<select id="selectAll" resultType="Ntables">
select * from ntable;
</select>
<select id="selectNtableId" resultType="com.xm.Model.Ntables">
select * from Ntable
where nid=#{nid};
</select>
<select id="selectNtableName" resultType="com.xm.Model.Ntables">
select * from Ntable
where nname=#{nname};
</select>
</mapper>
Dao
package com.xm.dao;
import com.xm.Model.Ntables;
import java.util.List;
/**
* @Author:MG
* @Package:com.xm.dao
* @Project:app
* @name:Ntable
* @Date:2023/8/15 18:13
* @Filename:Ntable
*/
public interface Ntable {
List<Ntables> selectAll();
void addNtable(Ntables ntable);
void DeleteNtable(Ntables ntable);
void UpdateNtable(Ntables ntables);
Ntables selectNtableId(Ntables ntable);
Ntables selectNtableName(Ntables ntable);
}
Bean
package com.xm.Model;
/**
* @Author:MG
* @Package:com.xm.dao
* @Project:app
* @name:Ntable
* @Date:2023/8/15 18:08
* @Filename:Ntable
* 实体类
*/
public class Ntables {
String nname;
Integer nage;
Integer nid;
public Ntables(Integer nid) {
this.nid = nid;
}
public Ntables(String nname, Integer nage, Integer nid) {
this.nname = nname;
this.nage = nage;
this.nid = nid;
}
public Ntables() {
}
public String getNname() {
return nname;
}
public void setNname(String nname) {
this.nname = nname;
}
public Integer getNage() {
return nage;
}
public void setNage(Integer nage) {
this.nage = nage;
}
public Integer getNid() {
return nid;
}
public void setNid(Integer nid) {
this.nid = nid;
}
@Override
public String toString() {
return "Ntables{" +
"nname='" + nname + '\'' +
", nage=" + nage +
", nid=" + nid +
'}';
}
}
ServiceTest
package com.xm.Service.Ntable;
import com.xm.Model.Ntables;
import com.xm.dao.Ntable;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author MG
* @version 1.0
* ip : 10.70.10.30
* @description:
* @date 2023/8/17 16:27
*/
public class TestNtbale {
public static void main(String[] args) throws IOException {
TestNtbale testNtbale=new TestNtbale();
List<Ntables> ntables = testNtbale.selectNatable();
for (int i = 0; i < ntables.size(); i++) {
Ntables ntable = ntables.get(i);
System.out.println("Name: " + ntable.getNname());
System.out.println("Age: " + ntable.getNage());
System.out.println("ID: " + ntable.getNid());
System.out.println("------------------------");
}
}
//添加逻辑
public void addNatable( Ntables ntable) throws IOException {
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
//List<Object> users = sqlSession.selectList("user.selectALL");
//代理执行sql
Ntable mapper = sqlSession.getMapper(Ntable.class);
mapper.addNtable(ntable);
//释放资源
sqlSession.close();
}
//删除逻辑
public void DeleteNatable(int id) throws IOException {
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
//List<Object> users = sqlSession.selectList("user.selectALL");
//代理执行sql
Ntable mapper = sqlSession.getMapper(Ntable.class);
Ntables ntable=new Ntables() ;
ntable.setNid(id);
mapper.DeleteNtable(ntable);
//释放资源
sqlSession.close();
}
//修改逻辑
public void UpdateNatable(Ntables ntable) throws IOException {
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
//List<Object> users = sqlSession.selectList("user.selectALL");
//代理执行sql
Ntable mapper = sqlSession.getMapper(Ntable.class);
mapper.UpdateNtable(ntable);
//释放资源
sqlSession.close();
}
//查询逻辑
public Ntables selectNatableId(Ntables ntable) throws IOException {
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
//List<Object> users = sqlSession.selectList("user.selectALL");
//代理执行sql
Ntable mapper = sqlSession.getMapper(Ntable.class);
Ntables ntables = mapper.selectNtableId(ntable);
//释放资源
sqlSession.close();
return ntables;
}
//查询逻辑
public Ntables selectNatableName(Ntables ntable) throws IOException {
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
//List<Object> users = sqlSession.selectList("user.selectALL");
//代理执行sql
Ntable mapper = sqlSession.getMapper(Ntable.class);
Ntables ntables = mapper.selectNtableName(ntable);
//释放资源
sqlSession.close();
return ntables;
}
//查询逻辑
public List<Ntables> selectNatable() throws IOException {
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
//List<Object> users = sqlSession.selectList("user.selectALL");
//代理执行sql
Ntable mapper = sqlSession.getMapper(Ntable.class);
List<Ntables> ntables = mapper.selectAll();
//释放资源
sqlSession.close();
return ntables;
}
}
spring
Spring 是什么
Spring 是一个开源的轻量级应用程序框架,用于构建企业级 Java 应用程序。它提供了一种全面的编程和配置模型,为开发者创建可扩展、松耦合和模块化的应用程序提供了支持。
Spring 框架的核心原则是依赖注入(Dependency Injection)和面向切面编程(Aspect-Oriented Programming)。依赖注入通过将对象之间的依赖关系委托给容器来实现,使得组件之间的解耦程度更高,代码更加容易理解和测试。而面向切面编程则通过将横切关注点(例如事务管理、日志记录等)从主业务逻辑中分离出来,提供了更好的模块性、可重用性和可维护性。
Spring 框架包含了许多模块和扩展,例如 Spring Core、Spring MVC、Spring Boot、Spring Data、Spring Security 等,每个模块都可以根据需要进行选择和使用。这些模块提供了各种功能,包括控制反转(Inversion of Control)、面向切面编程、数据库访问、事务管理、Web 开发等。
Spring 的特点包括:
- 轻量级:Spring 框架的设计目标是保持轻量级和非侵入性,不强制使用者遵循特定的编程模型。
- 高度可扩展:Spring 框架通过模块化的设计和插件扩展机制,可以根据需要选择性地集成其他框架或库。
- 松耦合:通过依赖注入和接口编程,Spring 框架降低了组件之间的耦合度,使得代码更易于维护和测试。
- 全面的功能:Spring 提供了众多功能模块,涵盖了企业级应用程序开发的各个方面。
- 支持多种应用场景:无论是传统的服务器端应用、分布式应用、RESTful Web 服务还是大数据应用,Spring 都有相应的模块和扩展来支持。
什么是IOC
IOC(Inversion of Control,控制反转)是一种软件设计原则,也是面向对象编程中的一种思想。它将对象的依赖关系的创建、注入和管理由程序员托管给容器或框架来完成,从而实现了程序流程的反转。
在传统的编程模式中,对象之间的依赖关系通常是通过直接创建和管理对象之间的引用来实现的。而在IOC模式中,对象不再负责创建和管理它们所依赖的对象,而是通过外部的容器来完成这些工作。
IOC 的核心思想是:控制权的反转。即,把对象依赖关系的创建和管理,交给了容器来完成,程序员只需定义对象之间的依赖关系,并通过配置方式告诉容器如何创建和注入这些对象。
使用IOC的好处包括:
- 解耦:通过IOC容器管理对象之间的依赖关系,降低了类之间的耦合度。
- 可测试性:通过IOC容器注入依赖,可以方便地进行单元测试,提高代码的可测试性。
- 可扩展性:通过配置方式定义对象之间的依赖关系,方便后续的扩展和维护。
在Java开发中,Spring框架是一个知名的IOC容器框架,它提供了强大的IOC功能,可以灵活地管理对象之间的依赖关系。
总而言之,IOC是一种通过容器控制对象依赖关系创建和管理的设计思想,可以提高代码的可维护性、可测试性和扩展性。
Bean
在Spring框架中,Bean是被Spring容器管理的对象。它是Spring应用程序的基本构建块,通过Spring容器创建、组装和管理。
在Spring中,Bean可以理解为任何由Spring容器实例化、组装和管理的对象。这些对象可以是应用程序的核心业务对象、数据库连接、事务管理器、日志记录器等等。
要定义一个Bean,可以使用@Component
注解或其它更具体的注解(如@Service
、@Repository
、@Controller
等)来标记一个类,表示它是一个Spring Bean。例如:
@Component
public class MyBean {
// ...
}
这样,当Spring容器启动时,它会自动扫描并创建MyBean
的实例,并将其纳入容器的管理。
除了注解方式,还可以在XML配置文件中显式地定义Bean。例如:
<bean id="myBean" class="com.example.MyBean"/>
在上述例子中,Spring容器将会创建一个MyBean
类的实例,并且将其注册到容器中,以供后续使用。
无论采用注解方式还是XML配置方式,Spring容器都会负责管理Bean的生命周期、依赖注入、AOP(面向切面编程)等操作。我们可以通过在Bean类中使用@Autowired
注解来实现依赖注入,即将一个Bean作为另一个Bean的依赖。
通过Spring的IoC容器,我们可以方便地创建、管理和使用Bean,实现了对象之间的解耦、灵活的配置和更好的可测试性。
Bean标签的范围配置
在Spring的XML配置文件中,可以使用<bean>
标签来定义和配置Bean。<bean>
标签可以使用以下属性来指定Bean的范围:
-
默认范围(singleton):
<bean id="myBean" class="com.example.MyBean" />
如果不显式指定范围属性,默认情况下Bean的范围为singleton,也就是单例模式。这意味着在整个应用程序上下文中,只会创建一个实例,并且该实例将被共享和重用。
-
原型范围(prototype):
<bean id="myBean" class="com.example.MyBean" scope="prototype" />
当指定
scope="prototype"
时,每次通过Spring容器获取Bean的时候,都会创建一个新的Bean实例。
除了上述两种最常用的范围,Spring还提供了其他一些选择,例如:
-
请求范围(request):
<bean id="myBean" class="com.example.MyBean" scope="request" />
当指定
scope="request"
时,每个HTTP请求都会创建一个新的Bean实例。这个范围通常在web应用程序中使用,在每次请求中,Spring会为每个请求创建一个新的Bean实例。 -
会话范围(session):
<bean id="myBean" class="com.example.MyBean" scope="session" />
当指定
scope="session"
时,每个用户会话都会创建一个新的Bean实例。这个范围通常在web应用程序中使用,在用户会话期间,Spring会为每个会话创建一个新的Bean实例。 -
全局会话范围(global session):
<bean id="myBean" class="com.example.MyBean" scope="global session" />
当指定
scope="global session"
时,每个全局会话都会创建一个新的Bean实例。这个范围通常与分布式环境下的集群会话场景相关。
需要注意的是,请求范围、会话范围和全局会话范围这三种范围仅适用于基于Web的应用程序。在非Web应用程序中,只能使用默认范围(singleton)和原型范围(prototype)。
以上是在XML配置文件中配置Bean的范围的方法。当然,还可以使用注解方式来配置Bean的范围,例如在Bean类上使用@Scope
注解。但无论使用XML配置还是注解方式,最终都会被转化成相应的容器配置信息来管理Bean的范围。
Bean的生命周期配置
在Spring中,可以通过配置来管理Bean的生命周期。下面是一些常用的方法:
-
初始化方法和销毁方法:
可以使用init-method
和destroy-method
属性来指定Bean的初始化方法和销毁方法。例如:<bean id="myBean" class="com.example.MyBean" init-method="init" destroy-method="destroy" />
在上述例子中,
init-method
指定了Bean的初始化方法为init
,destroy-method
指定了Bean的销毁方法为destroy
。这两个方法可以是Bean类中的任意公共方法。 -
实现接口:
Bean类可以实现一些特定的接口,以便在Bean的创建、初始化和销毁阶段执行相应的逻辑。常用的接口包括:InitializingBean
接口:实现afterPropertiesSet
方法,在Bean的属性设置完成后执行初始化逻辑。DisposableBean
接口:实现destroy
方法,在销毁Bean之前执行清理逻辑。
例如:
public class MyBean implements InitializingBean, DisposableBean { // ... @Override public void afterPropertiesSet() throws Exception { // 初始化逻辑 } @Override public void destroy() throws Exception { // 销毁逻辑 } }
-
注解方式:
还可以使用注解来标记初始化方法和销毁方法。常用的注解包括:@PostConstruct
:标记在方法上,表示该方法在Bean的属性设置完成后执行初始化逻辑。@PreDestroy
:标记在方法上,表示该方法在销毁Bean之前执行清理逻辑。
例如:
public class MyBean { // ... @PostConstruct public void init() { // 初始化逻辑 } @PreDestroy public void destroy() { // 销毁逻辑 } }
通过以上的配置方式,可以在Bean的创建、初始化和销毁阶段执行相应的逻辑,实现对Bean生命周期的管理。需要根据具体的需求选择合适的方式来配置Bean的生命周期。
Bean实例化三种方式
在Spring中,可以使用以下三种方式实例化Bean:
-
构造方法实例化:
最常见的方式是通过调用Bean类的构造方法来实例化Bean。在XML配置文件或者使用注解时,可以指定构造方法的参数来传递依赖项。XML配置方式示例:
<bean id="myBean" class="com.example.MyBean"> <constructor-arg ref="dependencyBean" /> </bean>
注解方式示例:
@Component public class MyBean { private DependencyBean dependencyBean; public MyBean(DependencyBean dependencyBean) { this.dependencyBean = dependencyBean; } // ... }
-
静态工厂方法实例化:
另一种方式是通过调用Bean类中的静态工厂方法来实例化Bean。这个静态方法负责创建Bean的实例并返回。XML配置方式示例:
<bean id="myBean" class="com.example.MyBeanFactory" factory-method="createMyBean" />
Java代码示例:
public class MyBeanFactory { public static MyBean createMyBean() { // 创建并返回Bean实例 } }
-
实例工厂方法实例化:
还可以使用实例工厂方法(非静态)来实例化Bean。这个实例方法属于一个专门的工厂类,负责创建Bean的实例并返回。XML配置方式示例:
<bean id="myBeanFactory" class="com.example.MyBeanFactory" /> <bean id="myBean" factory-bean="myBeanFactory" factory-method="createMyBean" />
Java代码示例:
public class MyBeanFactory { public MyBean createMyBean() { // 创建并返回Bean实例 } }
通过以上三种方式,可以根据具体的情况和需求来实例化Bean。
Bean的注入类型
在Spring中,可以使用以下几种方式进行Bean的注入:
-
构造方法注入:
通过构造方法将依赖项注入到Bean中。可以使用<constructor-arg>
元素进行配置,或者使用@Autowired
注解。XML配置方式示例:
<bean id="myBean" class="com.example.MyBean"> <constructor-arg ref="dependencyBean" /> </bean>
注解方式示例:
@Component public class MyBean { private DependencyBean dependencyBean; @Autowired public MyBean(DependencyBean dependencyBean) { this.dependencyBean = dependencyBean; } // ... }
-
Setter方法注入:
通过Setter方法将依赖项注入到Bean中。可以使用<property>
元素进行配置,或者使用@Autowired
注解。XML配置方式示例:
<bean id="myBean" class="com.example.MyBean"> <property name="dependencyBean" ref="dependencyBean" /> </bean>
注解方式示例:
@Component public class MyBean { private DependencyBean dependencyBean; @Autowired public void setDependencyBean(DependencyBean dependencyBean) { this.dependencyBean = dependencyBean; } // ... }
-
字段注入:
直接在字段上使用@Autowired
注解将依赖项注入到Bean中。注解方式示例:
@Component public class MyBean { @Autowired private DependencyBean dependencyBean; // ... }
-
方法注入:
通过在方法上使用@Autowired
注解将依赖项注入到Bean中。注解方式示例:
@Component public class MyBean { private DependencyBean dependencyBean; @Autowired public void setDependencyBean(DependencyBean dependencyBean) { this.dependencyBean = dependencyBean; } // ... }
以上是常用的Bean注入方式。可以根据具体的需求和情况选择适合的注入方式。同时,还可以结合使用@Qualifier
注解来指定具体的依赖项,以解决多个相同类型的Bean存在的歧义性。
相关APi
Spring提供了多个与Bean管理相关的API,下面列举了几个常用的API:
-
BeanFactory:
BeanFactory是Spring框架中最基本的接口,定义了IoC容器的基本功能。它提供了获取Bean实例、配置元数据管理、生命周期控制等方法。 -
ApplicationContext:
ApplicationContext是BeanFactory的子接口,它在BeanFactory的基础上增加了更多的企业级特性和功能,例如国际化支持、事件发布机制、AOP等。 -
BeanDefinition:
BeanDefinition表示一个Bean的定义信息,包括Bean的类型、作用域、依赖关系等。通过BeanDefinition可以创建和管理Bean实例。 -
BeanPostProcessor:
BeanPostProcessor是一个接口,用于在Bean实例化和依赖注入过程中进行扩展和自定义操作,例如初始化前后的处理、属性值修改等。 -
BeanFactoryPostProcessor:
BeanFactoryPostProcessor是BeanPostProcessor的子接口,用于在容器实例化Bean之前对BeanFactory进行修改和自定义操作,例如修改Bean定义、动态注册Bean等。 -
@Autowired:
@Autowired是Spring的注解之一,用于自动装配(依赖注入)Bean。它可以用在构造方法、Setter方法、字段和方法参数上,通过类型匹配或者使用@Qualifier注解指定具体的Bean来完成自动装配。 -
@ComponentScan:
@ComponentScan是Spring的注解之一,用于扫描指定包及其子包下的类,并将被@Component、@Service、@Repository等注解标记的类自动注册为Bean。 -
@Configuration:
@Configuration是Spring的注解之一,用于标记一个类为配置类,其中定义的@Bean方法可以用于创建和配置Bean。
这些是Spring中常用的与Bean管理相关的API和注解,通过它们可以实现灵活的Bean管理和依赖注入。
Spring配置数据源
在Spring中配置数据源通常使用的是DataSource
接口的实现类。以下是一种常见的配置方式,使用Spring提供的org.springframework.jdbc.datasource.DriverManagerDataSource
类作为数据源实现:
-
导入相关依赖:
在项目的pom.xml
文件中添加Spring JDBC和数据库驱动的依赖。例如,如果使用MySQL数据库,可以添加以下依赖:<dependencies> <!-- Spring JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- MySQL Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <!-- 其他依赖... --> </dependencies>
-
配置数据源:
在Spring的配置文件(通常是application.properties
或application.yml
)中设置数据源的相关属性,例如数据库URL、用户名和密码等。以application.properties
为例:spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-
创建数据源Bean:
在Spring的配置类中创建数据源Bean,并将其注入到需要使用的地方。例如,使用@Configuration
注解创建一个配置类,并使用@Bean
注解创建数据源Bean:import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); return dataSource; } }
-
使用数据源:
在需要使用数据库连接的地方,可以通过@Autowired
注解将数据源注入到相应的对象中。例如,在DAO类中使用数据源执行数据库操作:import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import javax.sql.DataSource; @Repository public class MyDao { private final JdbcTemplate jdbcTemplate; @Autowired public MyDao(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } // 使用jdbcTemplate执行数据库操作... }
通过以上配置,你就可以在Spring中成功配置数据源并进行数据库操作了。请根据实际情况调整配置文件和代码中的数据库类型和相关属性。
通过spring创建实体类对象
通过Spring创建实体类对象通常可以利用依赖注入的方式来实现。下面是一种常见的方式:
-
在实体类上添加相关注解:
在需要被Spring管理的实体类上添加@Component
、@Service
、@Repository
等注解之一,以标识该类为Spring的Bean。import org.springframework.stereotype.Component; @Component public class MyEntity { // 实体类的属性和方法... }
-
在使用的地方注入实体类对象:
在需要使用实体类对象的地方,可以通过构造方法、Setter方法或字段上的@Autowired
注解来注入实体类对象。-
通过构造方法注入:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { private final MyEntity myEntity; @Autowired public MyService(MyEntity myEntity) { this.myEntity = myEntity; } // 使用MyEntity对象进行业务操作... }
-
通过Setter方法注入:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { private MyEntity myEntity; @Autowired public void setMyEntity(MyEntity myEntity) { this.myEntity = myEntity; } // 使用MyEntity对象进行业务操作... }
-
通过字段注入:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private MyEntity myEntity; // 使用MyEntity对象进行业务操作... }
-
-
在Spring的配置类中开启组件扫描:
在Spring的配置类上添加@ComponentScan
注解,指定需要扫描的包路径。这样,Spring会自动扫描并创建标记为组件的实体类对象。import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.example.package") public class AppConfig { // 配置相关的Bean... }
通过以上步骤,你就可以在Spring中创建和使用实体类对象了。注意,要确保实体类上添加了合适的注解,并且在配置类中开启了组件扫描。
AOP面向切面编程
AOP(Aspect-Oriented Programming)面向切面编程是一种软件开发的编程范式,旨在提供一种将横切关注点(如日志记录、事务管理等)与核心业务逻辑相分离的方式。
在使用AOP进行编程时,我们可以将应用程序的功能划分为两个主要部分:核心业务逻辑和横切关注点。核心业务逻辑是应用程序的主要功能,而横切关注点是在不同的模块或层之间共享的功能,例如日志记录、安全性、性能监控等。
AOP通过将这些横切关注点从核心业务逻辑中分离出来,使得我们可以独立地定义和维护它们,并在需要的时候选择性地将它们应用到核心业务逻辑中。
在Java中,使用AOP可以借助于特定的AOP框架,例如Spring框架中的AOP模块。下面是使用Spring AOP实现面向切面编程的基本步骤:
-
导入相关依赖:
在项目的pom.xml
文件中添加Spring AOP的依赖。例如,如果使用Spring Boot,可以添加以下依赖:<dependencies> <!-- Spring AOP --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 其他依赖... --> </dependencies>
-
定义切面类:
创建一个切面类,用于定义横切关注点的具体逻辑。切面类通常会使用@Aspect
注解进行标记,并在方法上使用不同的注解来定义切点和增强逻辑。import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void beforeAdvice() { System.out.println("执行前的日志记录..."); } }
上述示例中的
@Before
注解定义了一个前置通知,在执行com.example.service
包下的任意类的任意方法之前,打印一条日志信息。 -
配置AOP:
在Spring的配置类中,通过@EnableAspectJAutoProxy
注解开启自动代理功能并启用AOP。这样,Spring将能够扫描并识别切面类。import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @EnableAspectJAutoProxy public class AppConfig { // 配置相关的Bean... }
-
运行应用程序:
启动应用程序,当匹配到切点(切面定义的位置)时,AOP框架会自动在核心业务逻辑执行前、后或异常的时候执行切面类中定义的增强逻辑。
总结来说,在使用AOP进行面向切面编程时,需要定义切面类并配置AOP框架,使其能够识别和应用切面逻辑。这样就能实现将横切关注点与核心业务逻辑分离,并通过切面类来干预核心业务逻辑的执行。
什么是AOP
AOP(Aspect-Oriented Programming)是一种编程范式,旨在通过将横切关注点与核心业务逻辑相分离来提供更加模块化和可维护的代码结构。
在传统的面向对象编程中,我们将程序的功能划分为不同的类和方法,每个类负责完成特定的任务。然而,在实际开发中,存在一些与核心业务逻辑关注点无关但又必要的功能,例如日志记录、安全性、事务管理等。这些功能往往需要在不同的类和方法中重复编写代码,导致代码冗余、可维护性差。
AOP的思想是将这些横切关注点提取出来,形成一个独立的模块,并在需要的地方动态地将其织入到核心业务逻辑中。这样,我们可以将核心业务逻辑与横切关注点分离开来,使得代码更加清晰、可维护,并且可以在不修改核心业务逻辑代码的情况下灵活地添加、移除或修改这些横切关注点。
AOP的实现通常依赖于编译时或运行时的代码织入。代码织入是指将横切关注点插入到目标代码中的过程。常见的织入技术包括静态代理、动态代理和字节码操作等。
常见的AOP框架包括Spring AOP、AspectJ等。这些框架提供了一套机制和注解来定义横切关注点的位置,并在运行时自动将其织入到目标代码中。
总结来说,AOP是一种面向切面编程的范式,通过将横切关注点与核心业务逻辑分离,使得代码更加模块化、可维护。
怎么理解面向切面编程?
面向切面编程(Aspect-Oriented Programming,AOP)是一种软件开发的编程范式,它通过将横切关注点与核心业务逻辑相分离,来提供更加模块化和可维护的代码结构。
在传统的面向对象编程中,我们将程序的功能划分成不同的类和方法,每个类负责完成特定的任务。然而,在实际开发中,存在一些与核心业务逻辑无关但又必要的功能,比如日志记录、安全性、事务管理等。这些功能往往需要在不同的类和方法中重复编写代码,导致代码冗余和可维护性差。
面向切面编程的思想是将这些横切关注点从核心业务逻辑中抽取出来,形成一个独立的模块,称为切面(Aspect)。切面包含了与多个对象或方法相关的公共横切关注点。然后,将切面与核心业务逻辑进行织入(Weaving),将切面的功能动态地应用到核心业务逻辑中。
具体来说,面向切面编程通过定义切面和切点,以及在切点上执行增强(Advice)来实现横切关注点的功能。切点是指在应用程序中选择某个特定位置(比如方法执行的前、后或异常抛出等)的规则。增强定义了在切点上执行的具体操作,例如日志记录、权限检查等。切面则将切点和增强组合起来,提供了一种将横切关注点织入到核心业务逻辑中的机制。
面向切面编程的好处包括:
- 模块化:将横切关注点独立出来,使得代码更加模块化和可重用。
- 可维护性:减少了重复的代码,便于对横切关注点的修改和维护。
- 可扩展性:能够动态地添加、移除或修改横切关注点的功能。
- 提高代码的可读性和可测试性:核心业务逻辑与横切关注点分离,代码更加清晰易懂,也更便于单元测试。
总结来说,面向切面编程是一种通过将横切关注点与核心业务逻辑分离的方式,提供更加模块化和可维护的代码结构的编程范式。
AOP的作用
面向切面编程(AOP)的作用是在软件开发中提供一种机制,使代码更具模块化、可维护性和可扩展性。以下是AOP的几个主要作用:
-
分离关注点:AOP可以将与核心业务逻辑无关但又必要的功能(如日志记录、安全性、事务管理等)从核心业务逻辑中分离出来,并封装成独立的切面。这样可以提高代码的可读性和可维护性,减少代码冗余。
-
横切关注点的集中处理:通过使用AOP,可以将多个对象或方法共有的横切关注点(cross-cutting concerns)集中处理。例如,可以定义一个日志切面,在每个方法的执行前后记录日志,而无需在每个方法中都编写相同的日志代码。
-
提高代码重用性:通过将特定功能封装为切面,可以在多个类和方法中共享该功能。这样可以提高代码的重用性和可维护性。
-
提高代码的灵活性和可扩展性:使用AOP可以动态地添加、移除或修改切面,而不需要修改核心业务逻辑代码。这使得代码具有更高的灵活性和可扩展性,可以根据需求方便地进行功能的增减或修改。
-
降低耦合度:AOP通过将关注点与核心业务逻辑分离,降低了代码的耦合度。这使得系统更具扩展性和维护性,便于单元测试和重构。
总而言之,AOP的作用在于提供一种在软件开发中处理横切关注点的机制,使代码更具模块化、可维护性和可扩展性。它能够分离关注点、集中处理横切关注点、提高代码重用性、提高代码灵活性和降低代码的耦合度。
AOP中术语
在面向切面编程(AOP)中,有几个重要的术语,下面是其中一些常用的术语:
-
Aspect(切面):切面是一个模块,它包含了与多个对象或方法相关的公共横切关注点的实现。切面定义了在哪里以及如何进行横切关注点的处理。
-
Join point(连接点):连接点是在应用程序中的特定位置,例如方法的调用或异常的抛出。切面可以通过定义切点选择特定的连接点。
-
Pointcut(切点):切点是指在应用程序中选择特定连接点的规则。它表示切面要织入的方法或一组方法。例如,一个切点可能是选择所有Service层的方法。
-
Advice(增强):增强定义了在切点上执行的具体操作,也就是在特定连接点上执行的代码。常见的增强类型包括前置增强(Before advice)、后置增强(After advice)、环绕增强(Around advice)、异常处理增强(After-throwing advice)和返回通知增强(After-returning advice)。
-
Introduction(引入):引入允许向现有类添加新方法或属性。它可以使类具有额外的功能,而无需修改类本身的代码。
-
Target object(目标对象):目标对象是被一个或多个切面所通知的对象。它是包含核心业务逻辑的原始对象。
-
Proxy(代理):代理是AOP框架生成的一个对象,它包装了目标对象并实现了与切面相关的逻辑。通过使用代理,AOP可以在目标对象的方法执行前后添加额外的行为。
-
Weaving(织入):织入是指将切面的功能动态地应用到目标对象上的过程。织入可以在编译时、类加载时或运行时进行。
这些术语在AOP中都扮演着重要的角色,它们共同定义了AOP的核心概念和机制。
什么时候你想用AOP
- 日志记录:可以通过AOP在方法执行前后添加日志记录的功能,方便跟踪和调试程序。
- 安全性控制:AOP可以用于在方法调用前进行身份验证和权限检查,确保只有有权限的用户能够执行敏感操作。
- 事务管理:通过AOP可以将事务管理的代码与核心业务逻辑分离,使得事务处理更加简洁和可维护。
- 缓存管理:AOP可以用于在方法调用前进行缓存查询,在方法调用后更新缓存,提高系统性能。
- 异常处理:AOP可以捕获方法执行过程中的异常,并进行统一的处理和记录。
- 性能监控:通过AOP可以在方法调用前后计时,统计方法执行时间,并进行性能监控和优化。
- 资源释放:AOP可以用于在方法执行完毕后自动释放资源,避免资源泄漏。
AOP技术思想的实现
- 静态代理:静态代理是指手动编写代理类,在代理类中调用目标对象的方法,并在必要的地方添加额外的逻辑。这种方式需要在编译期间就确定代理关系,比较简单但不够灵活。
- 动态代理:动态代理是指在运行时动态地创建代理对象,无需手动编写代理类。Java中的动态代理主要通过
java.lang.reflect.Proxy
类和java.lang.reflect.InvocationHandler
接口实现。通过动态代理可以在方法执行前后进行切面逻辑的增强。 - 字节码操作:字节码操作是指通过修改字节码文件来实现切面逻辑的增强。在Java中,常用的字节码操作库有ASM、Byte Buddy等。通过这些库,可以在编译后的字节码文件中插入字节码指令,实现切面逻辑的织入。
- 注解驱动:注解驱动是指通过在代码中添加特定的注解来标识切面逻辑的执行点。在运行时,AOP框架会扫描代码中的注解,动态地生成代理对象,并将切面逻辑织入到目标方法中。常见的Java注解框架有Spring AOP和AspectJ。
使用AspectJ框架实现AOP
使用AspectJ框架实现AOP可以分为以下几个步骤:
- 添加依赖:首先,在项目中添加AspectJ框架的依赖。例如,如果使用Maven管理项目,可以在
pom.xml
文件中添加以下依赖:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
</dependency>
- 编写切面类:创建一个Java类作为切面类,该类包含了需要织入的切面逻辑。切面类需要使用
@Aspect
注解进行标识,并可以定义多个切点和增强方法。例如,下面是一个简单的切面类示例:
import org.aspectj.lang.annotation.*;
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.MyClass.myMethod(..))")
public void beforeAdvice() {
System.out.println("Before method execution");
}
@After("execution(* com.example.MyClass.myMethod(..))")
public void afterAdvice() {
System.out.println("After method execution");
}
}
上述示例中,@Before
和@After
注解分别表示在目标方法执行前和执行后织入切面逻辑。
- 配置切面:在项目的配置文件中配置AspectJ的相关信息。如果是使用Spring框架,可以在Spring配置文件中添加如下配置:
<aop:aspectj-autoproxy />
<bean id="loggingAspect" class="com.example.LoggingAspect" />
这样,Spring会自动通过AspectJ框架创建代理对象,并将切面逻辑进行织入。
- 编写目标类:编写需要被切入的目标类和方法。例如:
package com.example;
public class MyClass {
public void myMethod() {
System.out.println("Executing myMethod");
}
}
- 运行测试:编写一个简单的测试类,在其中使用目标类的对象调用方法。例如:
package com.example;
public class Main {
public static void main(String[] args) {
MyClass myObj = new MyClass();
myObj.myMethod();
}
}
运行测试代码时,AspectJ会自动织入切面逻辑,输出如下结果:
Before method execution
Executing myMethod
After method execution
以上就是使用AspectJ框架实现AOP的基本步骤。通过定义切面类和配置切面,AspectJ能够将切面逻辑与目标类的方法织入到一起,实现横切关注点的统一处理。
AspectJ框架
AspectJ是一个基于Java语言的AOP框架,它提供了一种强大而灵活的方式来实现横切关注点的织入。它不仅支持注解驱动的方式进行AOP,还可以使用更强大的编译时织入(Compile-Time Weaving)和类加载时织入(Load-Time Weaving)等方式。
AspectJ扩展了Java语言,并引入了一套专门的语法和概念来支持AOP。它的语法包括切点表达式(Pointcut Expression)和增强代码块(Advice),通过这些语法可以定义切点和增强逻辑。切点(Pointcut)用于定义在哪些连接点(Join Point)上织入切面逻辑,而增强代码块则是实际执行的切面逻辑。
AspectJ的主要特点包括:
-
支持多种织入方式:AspectJ支持编译时织入、类加载时织入和运行时织入等多种织入方式,可以根据需求选择最合适的织入策略。
-
强大的切点表达式:AspectJ提供了一套丰富而灵活的切点表达式语法,可以精确地定义需要织入的连接点。
-
多种增强类型:AspectJ支持多种增强类型,包括Before、After、Around等,可以在目标方法的不同执行点织入切面逻辑。
-
多种织入级别:AspectJ支持细粒度的织入控制,可以选择在类级别、方法级别或更细粒度的代码块级别进行织入。
-
良好的与IDE集成:AspectJ与主流的Java集成开发环境(如Eclipse)有良好的集成,提供了方便的开发工具和调试支持。
总的来说,AspectJ是一个功能强大且灵活的AOP框架,它可以帮助开发者通过定义切点和增强逻辑,实现横切关注点的统一处理和复用,提高代码的可维护性和可扩展性。
mybatis
配置坐标
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<!-- mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!--三个日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
在resource添加
loback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 工程名/项目名 -->
<contextName>project_name</contextName>
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<!--把>=debug的日志输出到控制台 -->
<appender name="SDTOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative %date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/info.log</file>
<rollingPolicy name="50M_FILE" class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/info.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>500</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>200MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative %date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>
<rollingPolicy name="50M_FILE" class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/error.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>100</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>200MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative %date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="com.qinghuazs.blog" level="INFO"/>
<!-- 开发阶段使用DEBUG 生产环境使用INFO -->
<root level="INFO">
<!--<root level="INFO">-->
<appender-ref ref="SDTOUT" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>
数据库映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置数据库连接环境信息,通过default属性切换不同environment-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库的连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///sjk1?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql的映射文件-->
<mapper resource="userMapper.xml"/>
</mappers>
</configuration>
单独的映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace名称空间 单独的sql映射文件 返回结果resultType对应类-->
<mapper namespace="text">
<select id="selectALL" resultType="com.user.pojo.user">
select * from user;
</select>
</mapper>
加载核心配置文件 ,获取SqlSessionFactory对象
//加载mybatis核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSessionFactory,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql 使用名称空间名字和id
List<Object> users = sqlSession.selectList("text.selectALL");
System.out.println(users);
//释放资源
sqlSession.close();
代理方法
-
在pom.xml配置坐标包括 mybatis依赖,驱动,junit,三个日志
-
在resource下添加数据库的配置文件和映射文件
//配置文件是加载映射文件的源路径,中间是斜杠 <mappers> <!--加载sql的映射文件--> <mapper resource="mapper/userMapper.xml"/> </mappers> <!--namespace名称空间 (自己的路径中间是.) 单独的sql映射文件 返回结果resultType对应类 (类的路径中间也是.)--> <mapper namespace="mapper.userMapper"> <select id="selectALL" resultType="mapper.user"> select * from user; </select> </mapper>
-
在映射文件相同位置添加对应接口和类
-
在main添加mybatis核心配置文件,获取SqlSessionFactory,通过.openSession()得到sqlSession
-
//代理执行sql userMapper mapper = sqlSession.getMapper(userMapper.class); List<user> users = mapper.selectALL(); System.out.println(users); //释放资源 sqlSession.close();
配置文件完成增删改查
MyBatis是一种简化了数据库访问的持久层框架,下面是一个包含增删改查操作的示例配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydatabase" />
<property name="username" value="myuser" />
<property name="password" value="mypassword" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
上述配置文件中:
environments
标签用于配置环境,包含事务管理器和数据源的配置。这里使用的是JDBC事务管理器和连接池数据源。dataSource
标签配置数据源的相关信息,例如驱动、URL、用户名和密码等。mappers
标签配置映射器(Mapper)文件的位置,这些文件将定义具体的SQL映射。
接下来,我们需要创建对应的映射器文件 UserMapper.xml
,该文件位于 com/example/mapper/
目录下。以下是一个示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<insert id="insertUser" parameterType="com.example.User">
INSERT INTO user (id, name, age) VALUES (#{id}, #{name}, #{age})
</insert>
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
<update id="updateUser" parameterType="com.example.User">
UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
<select id="getUserById" parameterType="int" resultType="com.example.User">
SELECT id, name, age FROM user WHERE id = #{id}
</select>
</mapper>
在上述映射器文件中,我们定义了以下操作:
<insert>
:插入用户记录到数据库。<delete>
:根据用户ID从数据库中删除用户记录。<update>
:根据用户ID更新数据库中的用户记录。<select>
:根据用户ID查询数据库中的用户记录。
以上配置完成后,你可以在Java代码中使用MyBatis的API来执行这些操作。例如,使用SqlSessionFactory
和SqlSession
接口来获取连接并执行SQL语句。
SpringMVC
框架:主要服务与web层,与web层的各种数据打交道,同时可以与Spring容器一起使用,也可以说是在Spring框架基础上的框架。SpringMVC框架主要是化身为前端控制器,对其各个组件进行控制,从而实现数据响应,获取请求数据。
创建第一个MVC项目
建议从Maven的webapp原型直接创建,可以直接运行
-
找到模块WEB (上面是xml,下面是目录)自动生成src\main\webapp\WEB-INF\web.xml
-
pom.xml添加war
-
添加tomcat
-
导坐标 springwebMVC servlet thymeleaf-spring5
-
扩展配置方式配置web.xml
-
在spring.xml配置扫包器,和视图解析器
-
在WEB-INF下创建templates目录,其中写各种页面
-
新建一个类@Controller,配置实现跳转功能
导包
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--springMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.24</version>
<version>5.2.10.RELEASE</version>
</dependency>
<!--日志-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.5</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--整合包 解析页面-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
配置web.xml
-
默认配置方式
<servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
扩展配置方式
<!-- 注册前端控制器 DispatcherServlet--> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--配置MVC的配置文件和位置--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> <!--将前端控制器Dispatcherservlet的初始化时间提前到服务器启动时--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
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"
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">
<!-- 注解扫描器配置 -->
<context:component-scan base-package="com.xiaoge.mvc.controller"></context:component-scan>
<!--视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- 数据源配置 -->
<!--
<context:property-placeholder location="c3p0.properties"></context:property-placeholder>
-->
</beans>
————————————————
版权声明:本文为CSDN博主「编程小朱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_66466770/article/details/127288236
Controller类
@Controller//为了扫包器可以找到
public class HelloController {
@RequestMapping(value = "/")//thymeleaf固定写法
public String index(){
//返回视图名称
return "index";
}
@RequestMapping(value = "/target")
public String totarget(){
//返回视图名称
return "target";
}
}
总结
浏览器发送请求,若请求地址符合前端控制器的url-pattern,该请求就会被前端控制器DispatcherServlet处理。前端控制器会读取SpringMVC的核心配置文件,通过扫描组件找到控制器,将请求地址和控制器中
@RequestMapping注解的value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。处理请求的方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器解析,加上前缀和后缀组成视图的路径,通过Thymeleaf对视图进行渲染,最终转发到视图所对应页面
@RequestMapping注解
@RequestMapping注解的功能
从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。
SpringMVC简介
什么是MVc
MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分M: Model,模型层,指工程中的JavaBean,作用是处理数据.
-
M: Model,模型层,指工程中的JavaBean,作用是处理数据
一类称为实体类Bean:专门存储业务数据的,如Studentl User 等
一类称为业务处理Bean:指Service或Dao对象,专门用于处理业务逻辑和数据访问。
-
V: View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据
-
c: Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器
MVC的工作流程:
用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器
SpringMVC的特点
- Spring家族原生产品,与I0C容器等基础设施无缝对接
- 基于原生的Servlet, 通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统-处理
- 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
- 代码清新简洁,大幅度提升开发效率
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- 性能卓著,尤其适合现代大型、超大型互联网项目要求
第一个MVC
使用SpringMVC技术开发web程序流程
- 创建web工程(Maven结构)
- 设置tomcat服务器,加载web工程(tomcat插件)
- 导入坐标(SpringMVC+Servlet)
- 定义处理请求的功能类(UserController)
- 设置请求映射(配置映射关系)
- 将SpringIMVC设定加载到Tomcat容器中
导包
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope><!--这一步不能丢-->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
创建三个类
//控制器类
@Controller
public class UserController {
@RequestMapping("/save")//映射的路径
@ResponseBody // 表示返回的是一个内容不是一个页面,响应的内容按我返回的东西改
public String save(){
System.out.println("User save...");
return ("info ");
}
}
//springMvc配置类
@Configuration
@ComponentScan("com.xiaoge.Controller") //配置类中添加控制器类的扫描
public class SpringMvcConfig {
}
//初始化servlet容器的配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer{
//加载springMVC对应的容器对象
@Override
protected WebApplicationContext createServletApplicationContext() {
//初始化容器对象
AnnotationConfigWebApplicationContext ctx=new AnnotationConfigWebApplicationContext();
//通过resistr方法将 MVC注册到容器中
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设定哪些请求归springMVC处理
@Override
protected String[] getServletMappings() {
//所有请求都归springMVC管理
return new String[]{"/"};
}
//加载spring对应的容器对象
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
总结
一次性工作
- 创建工程,设置服务器,加载工程
- 导入坐标
- 创建web容器启动类,加载SpringMVc配置,并设置SpringIMVC请求拦截路径
- SpringMVc核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
多次工作
- 定义处理请求的控制器类
- 定义处理请求的控制器方法,并配置映射路径(@RequestMapping) 与返回json数据(@ResponseBody)
流程分析
初始化过程
- 执行ServletContainersInitConfig类,初始化web容器
- 执行createServletApplicationContext方法,创建了webApplicationContext对象
- 加载SpringMvcConfig
- 执行@ComponentScan加载对应的bean
- 加载UserController,每个@RequestMapping的名称对应一个具体的方法
- 执行getServletMappings方法,定义所有的请求都通过SpringMVc
单次请求过程
- 发送请求localhost/save
- web容器发现所有请求都经过SpringMVC,将请求交给springMVC处理
- 解析请求路径/ save
- 由/save匹配执行对应的方法save( )
- 执行save()
- 检测到有@ResponseBody直接将save()方法的返回值作为响应求体返回给请求方
请求与响应
@RequestMapping("/user")
方法注解,类注解
位置: SpringMVC控制器方法定义上方
作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
get请求的发送
//在工程名字后面加?name=ii&age=18
http://localhost:8080/web181_war_exploded/save?name=ii&age=18
get请求的接收
@RequestMapping("/save")
@ResponseBody
public String save(String name,int age){
String str=name;
int aage=age;
System.out.println("User save...name is :"+name+"年龄是:"+aage);
return ("welcome 名字是"+str+"年龄是:"+aage);
}
添加到ServletContainersInitConfig中WEB配种
//乱码处理
@Override
protected Filter[] getServletFilters() {
//添加过滤器
CharacterEncodingFilter filter=new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
第二个MVC
一.搭建环境
导坐标
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--添加这句话可以统一管理下面spring的版本-->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<!--三个spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--单独的servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--单独的jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
前端控制器配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置防乱码的过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--前端控制器配置-->
<servlet><!--固定写法-->
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--添加配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--正常情况发请求时候创建,下面语句作用就是启动服务器就创建-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
//这段中文过滤器必须在servlet过滤器的上面才行
<!--配置防乱码的过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
创建一个springmvc 的spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.MG.Controller" />
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--文件所在的目录-->
<property name="prefix" value="/WEB-INF/pages/" />
<!--文件的后缀名-->
<property name="suffix" value=".jsp" />
</bean>
<!-- 开启MVC框架注解的支持-->
<mvc:annotation-driven />
</beans>
搭建tomcat
删除原有的index.jsp 因为没有标签中文会乱码.
自己创建一个index.sjp
扫描以下这个类
//控制器类
@Controller
public class HelloController {
//请求路径
@RequestMapping(path = "/hello")
public String sayHello(){
System.out.println("Hello SpringMVC");
return "success";
}
}
二.流程步骤
启动服务器,加载配置文件
<!--正常情况发请求时候创建,下面语句作用就是启动服务器就创建-->
<load-on-startup>1</load-on-startup>
- 配置该标签,启动服务器的时候 servlet会直接被创建成对象(DispatcherServlet)
- 创建该对象的时候,同时加载springmvc配置文件
- 在springmvc配置文件中,先进行注解扫描,将类扫描成一个对象
- 然后开启视图解析器,可以实现页面跳转
- 最后开启springmvc框架注解,可以扫描到类中的方法( @RequestMapping(path = “/hello”))
发生http请求,后台处理请求
-
编写一个超链接,点击可以发送请求到后端
-
请求先被
<servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
拦截,经过dispatcherServle传到类中的请求地址一样的对应方法
-
方法返回值后,指挥中心dispatcherServle,会经过视图解析器跳转到对应的页面(跟返回值一样的)
springMVC基于组件详细流程:
- 发送请求,前端控制器dispatcherServle去查找Controllor里面的哪个方法去执行
- 处理器映射器HandlerMapping去分析请求,返回一个执行链
- 处理器适配器(HandlerAdapter)操作执行方法把返回值返回到前端控制器dispatcherServle
- 前端控制器dispatcherServle拿到返回值后找视图解析器,返回view界面
- 跳转到对应页面
注解介绍
总结:
- 请求体参数 可接收 RequestBody
- 实体类属性参数 可接收
- 关键字对应 可接收
- 使得方法提前执行 @ModelAttribute
@RequestMapping(path = “/hello”)@RequestMapping(value = “/hello”)@RequestMapping( “/hello”)
-
作用:用于建立请求URL和处理请求方法之间的对应关系。
-
可以放到方法上面
-
可以放到类上面———用于表示具体的模块
-
超链接默认发送get请求
@RequestMapping(value = “/hello” )默认接收get请求,
@RequestMapping(value = “/hello” ,method=“RequestMethod.POST”),更改为POst请求
@RequestMapping(value = “/hello” ,params = {“username”}),调用方法时,必须传输一个username 属性,否则不能调用
-
headers 请求头控制
RequestBody
接收请求体参数,接收一堆参数
拿到请求体内容
<form action="request/body" method="post">
宠物名字:<input type="text" name="cat.name"/><br/>
宠物颜色:<input type="text" name="cat.color"/><br/>
<input type="submit" value="提交">
</form>
@Controller
@RequestMapping("/request")
public class RequestBody例子 {
@RequestMapping("/body")
public String request(@RequestBody String body){
System.out.println(body);
return "success";
}
}
运行结果:
cat.name=a&cat.color=b
@PathVariable
获取get请求路径参数
<a href="request/body/1" >ID路径请求</a>
@RequestMapping("/body/{id}")
public String request1( @PathVariable(name="id") int id){
System.out.println("请求路径附带id是 :"+id);
return "success";
}
@RequestHeader
<a href="request/testhead" >head请求 Accept测试</a>
@RequestMapping("/testhead")
public String head(@RequestHeader(value="Accept") String head){
System.out.println("请求路径附带的head是 :"+head);
return "success";
}
@ModelAttribute
使得方法提前执行
@SessionAttribute
可以存值,取值,删除值
@CookieValue
<a href="request/testCookieValue" >请求 testCookieValue</a>
@RequestMapping("/testCookieValue")
public String CookieValue(@CookieValue(value="JSESSIONID") String CookieValue){
System.out.println("请求路径附带的CookieValue是 :"+CookieValue);
return "success";
}
@RequestParam(name=“password”)
请求参数绑定
<a href="para/testpara?password=123" >para</a>
@Controller
@RequestMapping("/para")
public class ParaController {
@RequestMapping("/testpara")
public String testpara( @RequestParam(name="password") int pass){
System.out.println("密码:"+pass);
return "success";
}
}
-----------------------------
例子2
@RequestMapping("/testpara1")
public String testpara(@RequestParam(name = "password") int pass) {
System.out.println("密码:" + pass);
return "success";
}
<a href="para/testpara1?password=123" >hello3</a>
//普通字段传递
@Controller
@RequestMapping("/para")
public class ParaController {
@RequestMapping("/testpara")
public String testpara(int password,String username){
System.out.println("密码:"+password);
System.out.println("用户名:"+username);
return "success";
}
}
<a href="para/testpara?password=123&username=小明" >para</a>
//实体类传递
public class Peoples implements Serializable//实体类需要实现接口
@Controller
@RequestMapping("/people")
public class Save {
@RequestMapping("/save")
public String save(Peoples peoples){
System.out.println("保存"+peoples);
return "success";
}
}
<form action="people/save" method="get">
姓名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
金额:<input type="text" name="money"/><br/>
<input type="submit" value="提交">
</form>
如果一个实体类中引用了另一个实体类,表单提交name应该为
<form action="people/save" method="get">
姓名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
金额:<input type="text" name="money"/><br/>
宠物名字:<input type="text" name="cat.name"/><br/>
宠物颜色:<input type="text" name="cat.color"/><br/>
<input type="submit" value="提交">
</form>
Controllor不变,实体类需要引用了另一个实体类
类型转化器
为什么用它?
<%--表单中传递一个日期--%>
<form action="people/save" method="post">
生日:<input type="text" name="date"/><br/>
<input type="submit" value="提交">
</form>
在传递一个日期的时候,spring自动将字符串转化为date类型,但是如果填写的日期不规范,就会报错
怎么办?
创一个utils目录,写一个字符串转化其他类型的类
package com.MG.utils;
import org.springframework.core.convert.converter.Converter;
import javax.xml.transform.Source;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author MG
* @version 1.0
* ip : 10.70.10.30
* @description: 将字符串转化为Date类型
* @date 2023/8/25 10:49
*/
public class StrubgToDate implements Converter<String, Date> {
@Override
public Date convert(String s) {
//如果传进来的值是空的,那么就直接运行时异常,程序停在
if(s == null){
throw new RuntimeException("请输入数据");
}
DateFormat format= new SimpleDateFormat("yyyy-MM-dd");
//把字符串转化为日期
try {
return format.parse(s);
} catch (ParseException e) {
throw new RuntimeException("数据类型转换错误");
}
}
}
更改spring配置文件
添加一个类型转化器,在转化器中添加刚才的类,然后在MVC框架注解的支持中添加此类型转化器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置类型转化器-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.MG.utils.StrubgToDate"></bean>
</set>
</property>
</bean>
<!--开启注解扫描-->
<context:component-scan base-package="com.MG.Controller" />
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--文件所在的目录-->
<property name="prefix" value="/WEB-INF/pages/" />
<!--文件的后缀名-->
<property name="suffix" value=".jsp" />
</bean>
<!-- 开启MVC框架注解的支持--><!--添加类型转化器-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
</beans>
获取servlet原生的API
@Controller
@RequestMapping("/para")
public class ParaController {
@RequestMapping("/testpara")
public String testpara(int password, String username, HttpServletRequest request, HttpServletResponse response){
System.out.println("密码:"+password);
System.out.println("用户名:"+username);
System.out.println("获取到:"+request);
System.out.println("获取到:"+response);
return "success";
}
}
只需添加形参即可