SpringFramework学习笔记
所需基本依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>6.1.12</version>
</dependency>
</dependencies>
配置文件注册bean
配置文件基础模板
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
- 使用配置文件注册一个bean最简单的方式,参数为 null
<bean id="hello" class="org.example.pojo.HelloWorld"/>
- 如果 bean 需要传入参数,并且希望是通过有参构造来创建
<bean id="hello" class="org.example.pojo.HelloWorld">
<constructor-arg name="message" value="Hello World!"/>
</bean>
- 如果bean需要传入参数,并且希望是通过无参构造来创建
- property 里的参数同上
<bean id="hello" class="org.example.pojo.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
关于配置文件注册bean
- 赋值的原理是通过类中的set注入
- id 相当于一个变量名,class 是类文件路径来源,还可以加个 name 作为 别名,注意 ==id 开头小写==
- 有参构造和无参构造中的 name 是参数名, value 是默认传入的值
- ==constructor-arg通过有参构造创建,创建对象的同时赋值==
- ==property通过无参构造创建,创建对象后,再通过set方法赋值==
导入其他配置文件里的内容
<import resource="其他Spring配置文件.xml"/>
导入的配置文件和本身共有注册 bean,优先用自己的
赋值方法
1、下标赋值
<bean id="hello" class="org.example.pojo.HelloWorld">
<constructor-arg index="0" value="Hello World!"/>
</bean>
2、通过类型赋值
<bean id="hello" class="org.example.pojo.HelloWorld">
<constructor-arg type="java.lang.String" value="Hello World!"/></bean>
缺陷:
3、通过参数名赋值
<bean id="hello" class="org.example.pojo.HelloWorld">
<constructor-arg name="message" value="Hello World!"/>
</bean>
获取bean
ApplicationContext context = new ClassPathXmlApplicationContext("Spring配置文件.xml");
类 变量名 = context.getBean("beanID", 类.class);
Autowired
自动装填 @Autowired 先判断byType,再判断byName
public class People {
// 等价于@Nullable,对象可以为null
@Autowired(required = false)
private Cat cat;
@Autowired
// @Autowired 先判断byType,再判断byName
@Qualifier(value = "dog")
// 如果自动装配的环境比较复杂,无法通过一个@Autowired完成时,就要使用@Qualifer(value = "***")指定bean名
private Dog dog;
private String name;
}
按照原本的配置方式
<bean id="people" class="org.example.pojo.People">
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
<property name="name" value="呵帅"/>
</bean>
使用Autowired自动装配
开启注解的支持
<context:annotation-config/>
注册bean
<bean id="people" class="org.example.pojo.People" autowire="byName">
<property name="name" value="呵帅"/>
</bean>
我们使用完Autowired自动装配后,就可以不在配置文件里面配置参数对象 但是有几点需要注意:
- byName:按照属性名自动装配,和对象中set注入方法中的属性名一致
- byType:按照属性类型自动装配,和对象中的set方法里的属性类型一致
- 使用byType必须保证类型全局唯一,否则会报错
- 使用byName必须保证属性名全局唯一,否则会报错
修改自动装配方式
<bean id="people" class="org.example.pojo.People" autowire="byName">
<property name="name" value="呵帅"/>
</bean>
把 autowire 里面的参数修改成 byName 或者 byType 即可,默认为 byType
依赖注入DI(Dependecy Injection)
- 依赖注入是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源
注入方式
- **第一种,普通值注入,value
<property name="name" value="John"/>
- **第二种,引用注入,ref
<property name="address" ref="address"/>
- **第三种,数组注入,array
<property name="friends" >
<array>
<value>Jane</value>
<value>Tom</value>
<value>Mary</value>
</array>
</property>
- **第四种,键值对,map
<property name="cards">
<map>
<entry key="身份证" value="123456789012345678"/>
<entry key="银行卡" value="987654321098765432"/>
<entry key="信用卡" value="54444"/>
</map>
</property>
- **第五种,list注入,list
<property name="courses">
<list>
<value>Java</value>
<value>Python</value>
<value>C++</value>
</list>
</property>
- **第六种,set注入,set
<property name="interests">
<set>
<value>篮球</value>
<value>足球</value>
<value>乒乓球</value>
</set>
</property>
命名空间
P 命名空间
- **spring中的p命名空间就是为了更加方便的使用set方法注入属性内容,可以直接注入属性值,property
- 首先我们需要引入对应这个p命名空间的xml约束
xmlns:p="http://www.springframework.org/schema/p"
举个例子
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
按照我们原来的写法应该是这么写
<bean id="User" class="org.example.pojo.User">
<property name="age" value="18"/>
<property name="name" value="呵帅">
</bean>
改用P命名空间后是这样
<bean id="user" class="org.example.pojo.User" p:name="呵帅" p:age="18" scope="singleton"/>
- 设置代理模式:scope,默认scope是singleton单例模式
- 单例模式只允许创建一个实例,后续通过id获取的都是同一个实例
- 原型模式prototype,允许创建多个实例,每次获取都是新的实例
C 命名空间
- **spring中的c命名空间就是为了更加方便的使用有参构造方法注入,通过构造器注入,constructor-arg
- c命名空间注入,通过构造器注入,constructor-arg
- 首先我们需要引入对应这个p命名空间的xml约束
xmlns:c="http://www.springframework.org/schema/c"
- **通过使用名称的方式
<bean id="user2" class="org.example.pojo.User" c:name="呵帅2" c:age="18" scope="prototype"/>
- **通过使用索引的方式
<bean id="user2" class="org.example.pojo.User" c:_0="呵帅2" c:_1="18" scope="prototype"/>
mybatis
- DataSource:使用Spring的数据源代替mybatis的配置 c3p0 dbcp druid这是使用Spring提供的JDBC:org.springframework.jdbc.datasourceDataSource
- 使用Spring的数据源代替mybatis的配置 c3p0 dbcp druid这是使用Spring提供的JDBC:org.springframework.jdbc.datasource
添加maven
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.13.RELEASE</version>
</dependency>
<!--Spring操作数据库还需要一个spring-jdbc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
</dependency>
</dependencies>
配置文件mybatis
需要使用的文件

<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--DataSource:使用Spring的数据源代替mybatis的配置 c3p0 dbcp druid 这是使用Spring提供的JDBC:org.springframework.jdbc.datasource
--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_lean"/>
<property name="username" value="root"/>
<property name="password" value="Abc123"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:org/example/mapper/*.xml"/>
</bean>
<!--SqlSessionTemplate:就是我们之前使用的sqlSession Template:模板-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入,这是因为没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
resource/applicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="org.example.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
<bean id="userMapper2" class="org.example.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean></beans>
org/example/mapper/UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserMapper">
<select id="selectUser" resultType="user">
SELECT * FROM mybatis_lean.user;
</select>
<insert id="addUser" parameterType="user">
insert into mybatis_lean.user (id, name, pwd) values (#{id}, #{name}, #{pwd});
</insert>
<delete id="deleteUser" parameterType="int">
delete from mybatis_lean.user where id = #{id};
</delete>
</mapper>
注解开发mybatis
需要使用的文件

可以清晰的看出,少了很多不必要的文件
用类 MyConfiguration.class 文件代替配置文件
package org.example;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@ComponentScan("org.example.service")
@MapperScan("org.example.mapper")
public class MyConfiguration {
@Bean
public DataSource dataSource() {
return new PooledDataSource("com.mysql.cj.jdbc.Driver", "jdbc:mysql://localhost:3306/mybatis_lean", "root", "Abc123");
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean() {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource());
return bean;
}
}
mapper 层接口
package org.example.mapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.example.User;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
public List<User> selectUser();
@Insert("insert into user(id, name, pwd) VALUES(#{id}, #{name}, #{pwd})")
public int addUser(User user);
@Delete("delete from user where id=#{id}")
public int deleteUser(int id);
}
service 层接口
package org.example.service;
import org.example.User;
import java.util.List;
public interface UserService {
public List<User> selectUser();
public int addUser(User user);
public int deleteUser(int id);
}
service 层实现类
package org.example.service;
import org.example.User;
import org.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService{
@Autowired
UserMapper mapper;
@Override
public List<User> selectUser() {
return mapper.selectUser();
}
@Override
public int addUser(User user) {
return mapper.addUser(user);
}
@Override
public int deleteUser(int id) {
return mapper.deleteUser(id);
}
}
AOP
简单来说就是就是在运行期间加些事件进去
方式一:使用原生的Spring API接口
- **配置aop:需要导入aop的命名空间
<aop:config>
<!--配置切入点 expression:表达式,execution(要执行的位置 修饰词 返回值,列名 方法名 参数)-->
<aop:pointcut id="pointcut" expression="execution(* org.example.service..userServiceImpl.*(..))"/>
<!--执行环绕增强-->
<!--相当于将log这个类切入到pointcut上-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
实现 AfterReturningAdvice
- 在方法执行后运行
package org.example.Log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行力" + method.getName() + "方法后,返回值为:" + returnValue);
}
}
实现 MethodBeforeAdvice
- 在方法执行前运行
package org.example.Log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class log implements MethodBeforeAdvice {
@Override
// method:要执行的目标对象的方法
// args:目标对象方法的参数
// target:目标对象
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了");
}
}
方式二:自定义类
<bean id="diy" class="org.example.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面,ref 要引用的类-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="pointcut" expression="execution(* org.example.service.userServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
自定义的类
package org.example.diy;
public class DiyPointCut {
public void before() {
System.out.println("==========方法执行前===========");
}
public void after() {
System.out.println("==========方法执行后===========");
}
}
方式三:使用注解开发
- 开启注解支持 JDK(默认 expose-proxy=“false”) cglib(expose-proxy=“true”)
<aop:aspectj-autoproxy expose-proxy="false"/>
package org.example.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//使用注解方式实现AOP
@Aspect // 标注这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* org.example.service.userServiceImpl.*(..))")
public void before() {
System.out.println("====方法执行前====");
}
@After("execution(* org.example.service.userServiceImpl.*(..))")
public void after() {
System.out.println("====方法执行后====");
}
@Around("execution(* org.example.service.userServiceImpl.*(..))")
public void around(ProceedingJoinPoint pj) throws Throwable {
System.out.println("方法执行前");
// 执行方法
pj.proceed();
System.out.println("方法执行后");
}
}
调用运行
import org.example.service.userService;
import org.example.service.userServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理代理的是接口
userService userService = context.getBean("userService", userService.class);
userService.add();
userService.select();
}
}
- Posted on:
- December 20, 2024
- Length:
- 5 minute read, 966 words
- See Also: