本篇文章为你整理了Spring框架笔记(spring框架详解)的详细内容,包含有spring框架速成 spring框架详解 spring框架基础知识 spring框架视频讲解 Spring框架笔记,希望能帮助你了解 Spring框架笔记。
控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理。
使用IOC目的:
降低耦合度
通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象引用传递给他。也可以说依赖被注入到对象中。
IOC 底层原理
工厂模式(解耦操作),反射(得到.class文件),xml解析
工厂解耦过程:
IOC 解耦过程
Spring提供了IOC容器实现两种方式:(两个接口)
(1)BeanFactory:IOC容器里面最基本的实现方式,是Spring内部的接口,不提供开发人员使用
特点:加载配置文件时,不会创建对象,在获取或者使用的时候才会创建对象
(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用。
特点:加载配置文件的时候就会把配置文件对象进行创建
(1)在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
(2)在bean标签有很多属性,介绍常用的属性
id 属性:唯一标识
class 属性:创建对象所在类的全路径(包类路径)
(3)创建对象时, 默认也是执行无参构造方法
在spring配置文件配置对象创建,配置注入属性(xml中的配置)
bean id="UserName"
!--使用property完成属性注入
name:类里面属性名称
value:想属性里面注入的值
property name="UserName" value="jack" /property
/bean
// 1.加载spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml")
// 2.获取配置创建的对象
Orders orders = context.getBean("odders",Orders.class)
(2)在spring配置文件(xml中的配置)配置对象创建,配置注入属性
!--有参构造注入--
bean id="UserName"
constructor-arg name="UserName" value="jack" /constructor-arg
/bean
//特殊符号 1.把 进行转义 2.把带特殊符号的内容写到CDATA中
property name="address" value ![CDATA[ 南京 ]] /value /property
(3)注入属性-外部bean
bean id="userService"
//注入userDao对象 name属性:类里面属性名称 ref属性:创建userDao对象bean标签id值
// ref里面的名称要和id 的userDao一样
property name="userDao" ref="userDao" /property
/bean
bean id="userDao" /bean
Spring有两种类型 bean ,一种普通 bean ,另外一种是工厂 bean (FactoryBean)
普通 bean:在配置文件中定义 bean 类型就是返回类型
工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
第一步 创建类,让这个类作为工厂 bean ,实现接口 FactoryBean
第二步 实现接口里面的方法,在实现方法中定义返回的 bean 类型
bean 的作用域
如何设置单实例还是多实例
(1)在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例
(2)scope属性值:
第一个值,singleton,表示是单实例对象
第二个值,prototype,表示是多实例对象
bean id="" class="" scope="singleton" 或者 scope="prototype" /bean
为bean的属性设置值和对其他bean引用(调用set方法)
把 bean 实例传递 bean 后置处理器的方法
调用bean的初始化的方法(需要进行配置初始化方法)
把 bean 实例传递 bean 后置处理器的方法
bean 可以使用了(对象获取到了)
当容器关闭的时候,调用bean的销毁方法(想要进行配置销毁的方法)
public void initMethod(){
System.out.println("第三部 执行初始化的方法"); //在bean中加入init-methid标签写入initMethod方法
//创建销毁的方法
public void destroyMethod(){
System.out.println("第五部 执行销毁的方法"); //在bean中加入destroy-methid标签写入destroyMethod方法
public void testBean(){
ApplicationContext context = new ClassPathXmlApplicationContext(bean.xml);
Orders oeders = context.getBean("oeders",Orders.class);
System.out.println("第四部 获取到bean的");
System.out.println(oeders);
//手动让bean实例销毁
context.close();
//配置bean.xml文件
bean id="orders" init-methid="initMethod" destroy-method="destroyMethod"
property name="oname" value="手机" /property
/bean
创建类,实现接口 BeanPostProcessor,创建后置处理器 17集 21:00
public class MyBeanPost implements BeanPostProcessor {
bean id="dataSource"
property name="driverClassName" value="" /property //数据库驱动
property name="url" value="jdbc:mysql://locahost:3306/userDb" /property //数据库地址
property name="username" value="root" /property //数据库用户名
property name="password" value="root" /property //数据库密码
/bean
1.引入context名称空间
beans xmlns:context="http://www.springframework.org/schema/context"
/beans
2.引入外部属性文件
context:property-placeholder location="classpath:jdbc.properties"/
//配置连接池 value值写表达式,不写定值
bean id="dataSource"
property name="driverClassName" value="${prop.driverClass}" /property //数据库驱动
property name="url" value="${prop.url}" /property //数据库地址
property name="username" value="${prop.password}" /property //数据库用户名
property name="password" value="${prop.passName}" /property //数据库密码
/bean
什么是注解
注解是代码里面的特殊标记。格式:@注解名称(属性名称=属性值,属性名称=属性值)
//扫描包上层目录(所以文件全部扫描)
context:component-scan base-package="com.atguigu.spring5.dao,com.atguigu.spring5.service" /context:component-scan
第三步 创建类,在类上面添加创建对象注解
@component(value = "userService")
public class UserService{
public void add(){
System.out.println("service add ...");
第四部 组件设置扫描那些文件 context.include-filter
//部分扫描 include-filter
context:component-scan base-package="com.atguigu" use-default-filters="false"
context.include-filter type="annotation" expression="org.springframework.stereotype.Controller"/
/context:component-scan
//部分不扫描 exclude-filter
context:component-scan base-package="com.atguigu"
context.exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/
/context:component-scan
@AutoWired :根据属性类型进行自动装配
第一步 把 service 和 dao 对象创建,在service 和 dao 类添加创建对象的注解
第二步 在 service注入 dao 对象,在service 类添加 dao 类型属性,在属性上面使用注解
@Qualifier :根据属性名称进行注入
@Qualifier注解的使用和@AutoWired一起使用
@Resource :根据类型注入,可以根据名称注入
import javax.annotation.Resource;
@Resource (name = "userDaoImpl") //根据名称进行注入
private UserDao userDao;
import org.apringframework.context.annotation.Configuration;
//创建配置类,替代xml配置文件
@Configuration
@componentScan(basePackages = {"com.atguigu"})
public void Configuration{
//编写测试类
public void testService(){
//加载配置类
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean("userService",UserService.class);
userService.add();
什么是Aop
面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离。从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发效率。
通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
AOP底层原理
JDK动态代理
使用JDK动态代理,使用 Proxy 类里面的方法创建代理对象,调用 newProxyInstance 方法
方法里面有三个参数,
第一个参数:ClassLoader 类加载器
第二个参数:类 ? [ ] interfaces 增强方法所在的类,这个类实现的接口,支持多个接口
第三个参数:InvocationHandler 实现这个接口,创建代理对象,写增强的方法
newProxyInstance(ClassLoader loader , 类 ? [ ] interfaces ,InvocationHandler h)
创建接口,定义方法
package com.company.spring5;
//UserDao接口
public interface UserDao {
public int add(int a, int b);
public String upadte(String id);
创建接口实现类 UserDaoImpl,实现方法
package com.company.spring5;
public class UserDaoImpl implements UserDao{
@Override
public int add(int a, int b) {
return a + b;
@Override
public String upadte(String id) {
return id;
使用 Proxy
package com.company.spring5;
import java.util.Arrays;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.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 result = dao.add(1,2);
System.out.println("result:"+ result);
//创建代理对象代码
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;
AOP术语
AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和 Spring 框架一起使用,进行 AOP 操作
execution([权限修饰符][返回类型][类全路径][方法名称][参数列表])
//举例1 对com.atguigu.dao.BookDao类里面的 add 进行增强
excution(*com.atguigu.dao.BookDao.add(..))// *表示任意修饰符
//举例2 对com.atguigu.dao.BookDao类里面的所有方法进行增强
excution(*com.atguigu.dao.BookDao.*(..))
//举例3 对com.atguigu.dao包里面所有类,类里面所有方法进行增强
excution(*com.atguigu.dao.*.*(..))
!--开启注解扫描--
context:component-scan base-package="com.atguigu.spring5.aopanno" /context:component-scan
(2)使用注解创建 User 和 UserProxy 对象
import org.springframework.stereotype.Component;
//被增强类
@Component
public class User{
public void add(){
System.out.println("add....");
//增强类
@Component
@Aspect //第(3)步
public class UserProxy {
//前置通知
//@Before注解表示作为前置通知
@Before(value="execution(*com.atguigu.spring5.aopanno.User.add(..))")
public void before(){
System.out.println("before.....");
(3)在增强类上面添加注解@Aspect
(4)在 spring 配置文件中开启生成代理对象
!--开启 Aspect 生成代理对象--
aop:aspectj-autoproxy /aop:aspectj-autoproxy
配置不同类型的通知
(1)在增强类的里面,在作为通知方法上面添加通知类型的注解,使用切入点表达式配置内容
Spring框架对JDBC进行封装,使用 JdbcTemplate 方便实现对数据库操作
CSDN相关博客
bean id="dataSource" destroy-method="close"
property name="url" value="jdbc:mysql://user_db"/
property name="uesrname" value="root"/
property name="password" value="root"/
property name="driverClassName" value="com.mysql.jdbc.Driver"/
/bean
//xml中配置
context:component-scan base-package="com.atguigu" /context:component-scan
//Java文件中
@service
public class BookService{
//注入dao
@Autowired
private BookDao bookDao;
// Dao
@Repository
public class BookDaoImpl implements BookDao{
//注入 JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
(1)在 dao 进行数据库添加操作
(2)调用 JdbcTemplate 对象里面 update 方法实现添加操作
有两个参数
第一个参数: sql语句
第二个参数: 可变参数,设置 SQL 语句值
//修改
@Override
public void updateBook(Book book){
String aql="update t_book set username=?,ustatus=? where user_id=?"
Object[] args = {book.getUsername(),book.getUstatus(),book.getUserId()};
int update = JdbcTemplate.update(sql,args);
System.out.println(update);
第一个参数:SQL语句
第二个参数:RowMapper 是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
第三个参数:SQL语句值
JdbcTemplate 实现批量添加操作
batchUpdate(String sql,List Object[] batchArgs)
两个参数
第一个参数:SQL语句
第二个参数:List 集合,添加多条记录数据
事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果一个失败所有操作都失败
最典型场景:银行转账
事务四个特性(ACID)
创建 service ,搭建 dao ,完成对象创建和注入关系
(1)service 注入 dao ,在 dao 注入JdbcTemplate ,在 JdbcTemplate注入 DataSource
提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
接口 PlatformTransactionManager(org.springframework.transaction) 下的
DataDourceTransactionManger(org.springframework.jdbc.datasource)
!--开启事务注解--
tx:annotation-driven transaction-manager="transactionManager" /tx:annotation-driven
propagation: 事务传播行为
当一个事务方法被另外一个事务方法调用时候,这个事务方法如何进行
事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
有三个读问题:脏读、不可重复读、虚读
脏读:一个未提交的事务读取到了另一个未提交事务的数据。
不可重复读:一个未提交的数据读到了另外一个提交事务中的数据
虚读:一个未提交的事务读取到了另一个未提交事务添加的数据
解决:通过设置事务隔离性,解决上面问题
repeatable MySQL默认隔离级别
事务需要在一定时间内进行提交,如果不提交就会进行回滚
默认值是 -1(不超时)设置时间以秒为单位进行计算
读:查询操作,写:添加修改删除操作
readOnly 默认值为 false ,表示可以查询,可以添加修改删除操作
设置 readOnly 值为 true,设置为 true 之后,只能查询
整个Spring5基于java8,运行时兼容 JDK9,许多不建议使用的类型和方法在代码库中删除。
@Nullable 注解可以使用在方法上面,属性上面,参数上面,表示方法返回可以为空,属性可以为空,参数值可以为空
以上就是Spring框架笔记(spring框架详解)的详细内容,想要了解更多 Spring框架笔记的内容,请持续关注盛行IT软件开发工作室。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。