Java框架Spring(一)
一、Spring 是什么
Spring 是一个轻量级的,IOC和AOP的一站式Java 开发框架,是为了简化企业级应用开发而生的。
名词解释:
轻量级:框架体积小(核心模块)
IOC:Inversion of Control,直译过来是控制反转,把创建对象的控制权,反转给spring框架。以前,在程序中需要对象都是自己new。例如new StudentDao对象。
AOP:Aspect Oriented Programming, 直译过来就是面向切面编程。AOP 是一种编 程思想,是面向对象编程(OOP)的一种补充。
将程序中一些公共的非业务代码分离提取出来开,然后在业务代码执行时,给他们横切进来。底层使用的是动态代理的机制实现。在我们的业务代码不显示调用,但是执行业务代码,会通过代理对象调用非业务代码
一站式:除了核心的IOC和AOP功能之外,还对数据访问层,web层都有封装,所以是一站式的
二、spring的HelloWorld
1、使用的model类
package com.wbc.SpringPro.model;
public class Admin {
private String account;
private String password;
public Admin(String account, String password) {
this.account = account;
this.password = password;
}
public Admin() {
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2、spring 核心功能jar包
<!-- spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
3、spring的配置文件
在src/main/resources创建spring.xml文件作为配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--在spring配置文件中 注册spring管理的类 -->
<bean id="admin" class="com.wbc.SpringPro.model.Admin"></bean>
</beans>
4、Spring的helloWorld
package com.wbc.SpringPro.test;
import com.wbc.SpringPro.model.Admin;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
/*
ClassPathXmlApplicationContext是spring框架中的一个具体的实现类,负责生成管理程序中的对象
可以看作是一个容器,所以一般把spring框架称为spring容器或是IOC容器
new ClassPathXmlApplicationContext("spring.xml");用于生成spring容器
getBean("配置文件的id",.class文件) 从spring框架(spring容器)中获取需要的对象
控制反转---一种编程思想
把生成对象的控制权,反转给spring框架,矿建负责对整个对象的整个生命周期
对外提供获取对象的方法,我们在程序中哪里需要就在哪里获取即可
*/
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
Admin admin = applicationContext.getBean("admin", Admin.class);
Admin admin1 = (Admin) applicationContext.getBean("admin");
System.out.println(admin);
System.out.println(admin1);
}
}
5、相关说明、
ClassPathXmlApplicationContext是spring框架中的一个具体的实现类,负责生成管理程序中的对象 可以看作是一个容器,所以一般把spring框架称为spring容器或是IOC容器 new ClassPathXmlApplicationContext("spring.xml");用于生成spring容器 getBean("配置文件的id",.class文件) 从spring框架(spring容器)中获取需要的对象 也可以不传入。class文件,但在接收时需要强转
控制反转---一种编程思想 把生成对象的控制权,反转给spring框架,矿建负责对整个对象的整个生命周期 对外提供获取对象的方法,我们在程序中哪里需要就在哪里获取即可
三、spring的Bean管理
bean对象:由于把对象统一交给spring管理后,spring会对对象进行功能的增强,所以在spring框架中生成的对象,统一称为bean对象,用去区分是自己new的还是框架生成的。
spring的bean管理有两种方式
1、基于xml配置方式
<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype"></bean>使用bean标签配置需要让Spring管理的类 id="对象名称" 可以在getBean中获得到spring生成的对象 class="需要让spring管理的地址" scope="配置bean对象的作用域" scope="singleton" 单例的 在spring启动时就会创建对象,且始终只创建一个对象 scope="prototype" 原型的(多例的) 在每次获得对象时,都创建一个新的对象
IOC指的是让spring框架创建对象,创建对象的同时,还有一个动作称为依赖注入
依赖注入:在创建对象的时候,为对象赋值
依赖注入有两种方式 1、通过属性注入(set方法) 2、通过构造方法注入
(1)通过属性注入
<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype"> <!--调用的是类中的set方法--> <property name="account" value="admin"></property> <property name="password" value="111"></property> </bean>
需要注意的是,框架使用set get方法,需要我们在类中的成员变量和成员方法名称命名规范
(2)通过构造方法注入
<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype"> <!--调用构造方法的依赖注入--> <constructor-arg name="account" value="admin"></constructor-arg> <constructor-arg name="password" value="111"></constructor-arg> </bean>
(3)例:在test中通过service调用dao的方法
将AdminDao当作属性添加在AdminService中,并提供set和get方法
package com.wbc.SpringPro.service;
import com.wbc.SpringPro.dao.AdminDao;
import com.wbc.SpringPro.model.Admin;
public class AdminService {
AdminDao adminDao ;
public void saveAdmin() {
adminDao.saveAdmin();
}
public AdminDao getAdminDao() {
return adminDao;
}
public void setAdminDao(AdminDao adminDao) {
this.adminDao = adminDao;
}
}
AdminDao的定义
package com.wbc.SpringPro.dao;
import com.wbc.SpringPro.model.Admin;
public class AdminDao {
public void saveAdmin() {
System.out.println("保存admin");
}
}
通过bean标签配置在spring中
name
属性指定要注入的属性名称。ref
属性指定要注入的bean的ID(在Spring上下文中已经定义的其他bean)。即,ref="adminDao"
表示将名为adminDao
的bean注入到当前bean的adminDao
属性中。
<bean id="adminDao" class="com.wbc.SpringPro.dao.AdminDao"></bean> <bean id="adminService" class="com.wbc.SpringPro.service.AdminService"> <!--name是adminService的属性名 ref表示要注入的上下文中存在的bean的id--> <property name="adminDao" ref="adminDao"></property> </bean>
通过adminService调用
package com.wbc.SpringPro.test;
import com.wbc.SpringPro.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
AdminService adminService = (AdminService) applicationContext.getBean("adminService", AdminService.class);
adminService.saveAdmin();
}
}
2、使用注解进行配置
(1)开启注册扫描
<context:component-scan base-package="包名"> </context:component-scan>
(2)通过注解配置
@Component(value = "admin") @Scope(value = "prototype") /*等同于在配置文件中添加<bean id="admin" class="com.wbc.SpringPro.model.Admin" scope="prototype"></bean>*/
@Componen 通用类
@Service service层
@Repository dao层
以上注解都可以实现创建对象功能,只是为了后续扩展功能,在不同的层使用不 同的注解标记
@Scope(value=“prototype”) 原型
@Scope(value=“ singleton ”) 单例
package com.wbc.SpringPro.service;
import com.wbc.SpringPro.dao.AdminDao;
import com.wbc.SpringPro.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Service(value = "adminService")
public class AdminService {
@Autowired//自动注入
AdminDao adminDao ;
public void saveAdmin() {
adminDao.saveAdmin();
}
public AdminDao getAdminDao() {
return adminDao;
}
public void setAdminDao(AdminDao adminDao) {
this.adminDao = adminDao;
}
}
package com.wbc.SpringPro.dao;
import com.wbc.SpringPro.model.Admin;
import org.springframework.stereotype.Repository;
@Repository(value = "adminDao")
public class AdminDao {
public void saveAdmin() {
System.out.println("保存admin");
}
}
package com.wbc.SpringPro.test;
import com.wbc.SpringPro.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring.xml");
AdminService adminService = (AdminService) applicationContext.getBean("adminService", AdminService.class);
adminService.saveAdmin();
}
}
(3)自动注入
在属性上方通过注释的方式自动依赖注入
自动注入有两种值的匹配方式: 1、通过属性的类型进行查找 @Autowired(String提供): 用于在属性和属性的set方法上,如果写在属性上,set方法可以不需要 Autowired注解默认情况下要注入的值不能为空(required=true)
@Resource(jdk提供): 注入的值也不能为空,既可以通过属性的类型查找,又可以通过对象名查找 2、通过对象的名字进行查找 @Qualifier(value = "对象的名字")String提供 @Resource(name = "adminDao")jdk提供
3、注解配置于xml配置的优缺点
注解优点: 方便,直观,高效(代码少,没有配置文件的书写那么复杂)。
注解缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。
xml 优点:配置和代码是分离的,在 xml 中做修改,无需编译代码,只需重启服务器即可将新的 配置加载。
xml缺点:编写麻烦,效率低,大型项目过于复杂。
三、Spring 数据访问层管理
1、Spring管理JDBC
(1)添加依赖项
<!-- spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.2.RELEASE</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <!--阿里数据源 数据库链接管理组件--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
(2) 在spring配置文件中,通过bean标签添加对象的配置,使spring来管理对象
<!-- 阿里巴巴数据库链接管理对象,负责生成数据库链接对象,以及提供了数据库链接池功能 让spring管理数据库链接对象 相比myBatis的数据连接池,druid的功能更加灵活 --> <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmd?serverTimezone=Asia/Shanghai"></property> <property name="username" value="root"></property> <property name="password" value="Wbc11280"></property> <property name="initialSize" value="10"></property><!--初始化连接数量--> <property name="maxActive" value="20"></property><!--最大连接数量--> </bean> <!-- 配置spring中对jdbc进行封装的操作类 jdbcTemplate 在jdbcTemplace中注入druiDataSourse属性 --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="druidDataSource"></property> </bean>
(3)在dao层方法内执行sql
package com.wbc.SpringPro.dao;
import com.wbc.SpringPro.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository(value = "adminDao")
public class AdminDao {
@Autowired
JdbcTemplate jdbcTemplate;
public void saveAdmin() {
/*System.out.println("保存admin");*/
jdbcTemplate.execute("create table ..."); //主要执行创建表的ddl语句,没有返回值
jdbcTemplate.update("insert into admin(account,password,gender) values(?,?,?)","张三","111","男");
List<Admin> adminList=jdbcTemplate.query("select * from admin", new RowMapper<Admin>(){
@Override
public Admin mapRow(ResultSet resultSet, int i) throws SQLException {
Admin admin=new Admin();
admin.setAccount(resultSet.getString("account"));
admin.setPassword(resultSet.getString("password"));
return admin;
}
});
System.out.println(adminList);
}
}
执行成功
2、spring整合Mybaits
(1)为什么myBatis要整合阿里巴巴Druid连接池
-
性能优化:Druid是一个高性能的JDBC连接池,能够提供良好的性能表现,通过连接池技术可以有效地重用数据库连接,从而减少连接的创建和销毁开销。
-
监控和统计:Druid提供了丰富的监控和统计功能,能够实时监控数据库连接的使用情况、SQL执行情况等,有助于开发者快速发现并解决性能瓶颈和问题。
-
灵活配置:Druid支持多种配置选项,可以根据应用的需求进行灵活配置,如设置最小和最大连接数、连接超时时间等,以适应不同的使用场景。
-
安全性:Druid提供了SQL监控和防止SQL注入等安全特性,可以更好地保护数据库的安全。
-
易于集成:MyBatis已经提供了与Druid的良好集成支持,开发者可以方便地配置和使用Druid作为数据源,无需过多的修改。
(2)spring整合myBatis和Druid
Spring集成Mybatis其核心是将SqlSessionFactory交由Spring管理,并由 Spring管理对dao接口的代理实现。
我们从新创建一个JavaEE项目
jdk选择java8并添加web依赖
1)导入jar包
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wbc.ssm</groupId>
<artifactId>ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ssm</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>5.9.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!--阿里数据源 数据库链接管理组件-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--mybatis-spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
(2)搭建myBatis全局配置文件
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--myBatis全局配置文件-->
<!-- 配置日志-->
<settings>
<!-- 开启工作日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 将数据库中的下划线连接名称在java中自动转为驼峰体-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--在SqlMapperConfig.xml 中启用二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 为类配置别名-->
<typeAliases>
<!-- 为java中的类起别名-->
<package name="com.wbc.ssm.model"/>
</typeAliases>
<!-- 配置数据库连接关键信息配置到spring.xml中-->
<!--mapper映射也配置到spring.xml-->
</configuration>
(3)搭建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
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启spring注解的扫描功能 指定扫描包-->
<context:component-scan base-package="com.wbc.ssm"> </context:component-scan>
<!--
阿里巴巴数据库链接管理对象,负责生成数据库链接对象,以及提供了数据库链接池功能
让spring管理数据库链接对象 相比myBatis的数据连接池,druid的功能更加灵活
-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmd?serverTimezone=Asia/Shanghai"></property>
<property name="username" value="root"></property>
<property name="password" value="Wbc11280"></property>
<property name="initialSize" value="10"></property><!--初始化连接数量-->
<property name="maxActive" value="20"></property><!--最大连接数量-->
</bean>
<!--spring 管理sqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="druidDataSource"></property><!--将druid配置进dataSource-->
<property name="configLocation"
value="classpath:mybatis.xml"></property><!--配置myBatis配置文件-->
<!--扫描Mapper映射文件-->
<!--Mapper/*Mapper.xml表示Mapper包下的所有映射-->
<property name="mapperLocations" value="classpath:Mapper/*Mapper.xml">
</property>
</bean>
<!--生成dao层接口下的所有代理对象-->
<!--因此在dao层接口写不需要通过@Repository配置-->
<bean id="mapperFactory"
class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.wbc.ssm.dao"></property><!--指定包名-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">
</property>
</bean>
</beans>
由于通过spring 管理sqlSessionFactory对象所以不需要再手动获取sqlSessionFactory对象
(4)创建model类
package com.wbc.ssm.model;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Component
public class Admin implements Serializable {
private int id;
private String account;
private String password;
//lombok组件 在编译期间动态生成get、set方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Admin{" +
"id=" + id +
", account='" + account + '\'' +
", password='" + password + '\'' +
'}';
}
}
(5)创建dao层
package com.wbc.ssm.dao;
import com.wbc.ssm.model.Admin;
public interface LoginDao {
Admin login(Admin admin);
}
(6)创建dao层的映射文件
<?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需要和接口路径对应-->
<mapper namespace="com.wbc.ssm.dao.LoginDao">
<!--cache标签设置mapper开启二级缓存 flushInterval可以设置销毁时间,毫秒为单位 cache可以设置其他属性,包括是否只读,销毁策略等-->
<cache></cache><!--开启缓存需要返回的model类实现序列化接口Serializable-->
<select id="login" resultType="Admin">
select id,account,password from admin where id = #{id}
</select>
</mapper>
(7)创建service类调用dao层
package com.wbc.ssm.service;
import com.wbc.ssm.dao.LoginDao;
import com.wbc.ssm.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class LoginService {
@Autowired
LoginDao loginDao;
public Admin login(Admin admin) {
Admin admin1 = loginDao.login(admin);
return admin1;
}
}
(8)测试Test
package com.wbc.ssm.test;
import com.wbc.ssm.model.Admin;
import com.wbc.ssm.service.LoginService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//调用xml配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//获取service对象
LoginService loginService = applicationContext.getBean("loginService", LoginService.class);
//模拟web前端传入的数据
Admin admin = new Admin();
admin.setId(1);
//调用方法查询
Admin admin1 = loginService.login(admin);
System.out.println(admin1);
}
}
输出