栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SSM框架笔记(自用)-- Spring

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SSM框架笔记(自用)-- Spring

SSM框架笔记(自用)-- Spring Spring Framework系统架构

Spring程序开发步骤

核心概念 IoC( Inversion of Control)控制反转

使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转

Spring技术对Ioc思想进行了实现

Spring提供了一个容器,称为Ioc容器,用来充当Ioc思想中的外部。

IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean。

DI ( Dependency Injection)依赖注入

在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。

**目标:**充分解耦

使用IoC容器管理bean (IoC)

在IoC容器内将有依赖关系的bean进行关系绑定(DI)

最终效果

使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系

bean配置

创建Spring配置文件,配置对应类作为Spring管理的bean










    
    
    
    
        
    

注意事项:bean定义时id属性在同一个上下文中不能重复。

bean基础配置
类别描述
名称bean
类型标签
所属beans标签
功能定义Spring核心容器管理的对象
属性列表id : bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一;class : bean的类型,即配置的bean的全路径类名
范例bean id=“bookDao” class=“com.itheima.dao.imp1.BookDaoImpl” />
范例bean id=“bookService” class=“com.itheima. service.impl.BookServiceImpl”>
bean别名配置
类别描述
名 称name
类 型属性
所 属bean标签
功 能定义bean的别名,可定义多个,使用迹号(,)分号(;)空格()分隔
范 例bean id=“bookDao” name=“dao bookDaoImpl” class=“com.itheima.dao.imp1.BookDaoImpl” />
范 例bean name=“service,bookServiceImpl” class=“com.itheima. service.imp1.BookServiceImpl” />

注意事项:获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionException

NoSuchBeanDefinitionException: No bean named ‘bookServiceImpl’ available

bean作用范围配置
类别描述
名 称scope
类 型属性
所 属bean标签
功 能定义bean的作用范围,可选范围如下:singleton:单例(默认) prototype :非单例
范 例bean id=“bookDao” class=“com.itheima.dao.imp1.BookDaoImpl” scope=“prototype”/>
bean相关

Bean实例化三种方式 使用无参构造方法实例化

它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败


工厂静态方法实例化

工厂的静态方法返回Bean实例

public class StaticFactoryBean {
	public static UserDao createUserDao(){
		return new UserDaoImpl();
	}
}

工厂实例方法实例化

工厂的非静态方法返回Bean实例

public class DynamicFactoryBean {
	public UserDao createUserDao(){
		return new UserDaoImpl();
	}
}


bean的依赖注入 概念

依赖注入(Dependency Injection):它是 Spring 框架核心 IoC 的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。

那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

分析

构造方法

(1)setter注入

引用数据类型



	

简单数据类型


        
        

集合数据类型

public class BookDaoImpl implements BookDao {
    private int[] array;
    private List list;
    private Set set;
    private Map map;
    private Properties properties;

    public void setArray(int[] array) {
        this.array = array;
    }
    public void setList(List list) {
        this.list = list;
    }
    public void setSet(Set set) {
        this.set = set;
    }
    public void setMap(Map map) {
        this.map = map;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}


    
        
        
            
                100
                200
                300
            
        
        
        
            
                itcast
                itheima
                boxuegu
                chuanzhihui
            
        
        
        
            
                itcast
                itheima
                boxuegu
                boxuegu
            
        
        
        
            
                
                
                
            
        
        
        
            
                china
                henan
                kaifeng
            
        
    

(2)构造器注入



	

依赖注入方式选择

1、强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现;

2、可选依赖使用setter注入进行,灵活性强;

3、Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨;

4、如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入;

5、实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入;

6、自己开发的模块推荐使用setter注入。

Spring的重点配置

创建容器

方式一:类路径加载配置文件

ApplicationContext ctx = new ClassPathXm1ApplicationContext ("applicationContext.xml");

方式二∶文件路径加载配置文件

ApplicationContext ctx = new FileSystemxm1ApplicationContext("D:\applicationContext.xm1");

加载多个配置文件

ApplicationContext ctx = new ClassPathXmlApplicationContext ("bean1.xm1","bean2.xml");
容器相关

依赖注入相关

Spring注解开发

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。

配置数据源

数据源(连接池)的开发步骤:
① 导入数据源c3p0和druid的坐标和数据库驱动坐标,步骤略。
② 创建数据源对象;
③ 设置数据源的基本连接数据;
④ 使用数据源获取连接资源和归还连接资源。

applicationContext.xml加载jdbc.properties配置文件获得连接信息。

首先,需要引入context命名空间和约束路径:
● 命名空间:xmlns:context=“http://www.springframework.org/schema/context”
● 约束路径:http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd



Spring容器加载properties文件



        
        
        
        
    
纯注解开发

使用一个添加了 @configuration的config配置类来进行配置。

普通配置类注入

原始注解

使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。



  • 使用@Component或@Repository标识UserDaoImpl需要Spring进行实例化。
//@Component("userDao")
@Repository("userDao")   //@Component衍生注解
public class UserDaoImpl implements UserDao {
	@Override
	public void save() {
		System.out.println("save running... ...");
	}
}
  • 使用@Compont或@Service标识UserServiceImpl需要Spring进行实例化。
  • 使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入。
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
	
	@Resource(name="userDao")
	private UserDao userDao;
	@Override
	public void save() {
		userDao.save();
	}
}
  • 使用@Value进行字符串的注入。
@Repository("userDao")
public class UserDaoImpl implements UserDao {
	@Value("注入普通数据")
	private String str;
	@Value("${jdbc.driver}")
	private String driver;
	@Override
	public void save() {
		System.out.println(str);
		System.out.println(driver);
		System.out.println("save running... ...");
	}
}
  • 使用@Scope标注Bean的范围。
//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
	//此处省略代码
}
  • 使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法。
@PostConstruct
public void init(){
	System.out.println("初始化方法....");
}
@PreDestroy
public void destroy(){
	System.out.println("销毁方法.....");
}
Spring新注解

使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

注解说明
@Configuration用于指定当前类是一个Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定Spring在初始化容器时要扫描的包。作用和在Spring 的xml 配置文件中的一样
@Bean使用在方法上,标注将该方法的返回值存储到Spring 容器中
@PropertySource用于加载.properties文件中的配置
@lmport用于导入其他配置类
  • @Configuration
    @ComponentScan
    @Import
@Configuration  //标志该类是Spring的核心配置类
@ComponentScan("com.itheima")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}
  • @PropertySource
    @value
    @Bean
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {  //简单型依赖注入
	@Value("${jdbc.driver}")
	private String driver;
	@Value("${jdbc.url}")
	private String url;
	@Value("${jdbc.username}")
	private String username;
	@Value("${jdbc.password}")
	private String password;
}
//引用型依赖注入
@Bean(name="dataSource")  //Spring会将当前方法的返回值以指定名称存储到Spring容器中
public DataSource getDataSource() throws PropertyVetoException {
	ComboPooledDataSource dataSource = new ComboPooledDataSource();
	dataSource.setDriverClass(driver);
	dataSource.setJdbcUrl(url);
	dataSource.setUser(username);
	dataSource.setPassword(password);
	return dataSource;
}
Spring整合MyBatis

MyBatis程序核心对象分析

整合MyBatis

Spring整合JUnit 整合步骤

① 导入spring集成Junit的坐标(spring5 及以上版本要求 junit 的版本必须是 4.12 及以上–>)
② 使用@Runwith注解替换原来的运行期
③ 使用@ContextConfiguration指定配置文件或配置类
④ 使用@Autowired注入需要测试的对象
⑤ 创建测试方法进行测试

代码实现

① xml配置文件导入spring和junit坐标,代码略。

② 使用@Runwith注解替换原来的运行期

@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}

③ 使用@ContextConfiguration指定配置文件或配置类

@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}

④ 使用@Autowired注入需要测试的对象

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
	@Autowired
	private UserService userService;
}

⑤ 创建测试方法进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
	@Autowired
	private UserService userService;
	@Test
	public void testUserService(){
		userService.save();
	}
}

面向切面编程AOP 简介

AOP 是 OOP 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

作用及优势

作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强。
优势:减少重复代码,提高开发效率,并且便于维护。

核心概念
  • 代理(Proxy):SpringAOP的核心本质是采用代理模式实现的

  • 连接点(JoinPoint):在SpringAOP中,理解为任意方法的执行

  • 切入点(Pointcut):匹配连接点的式子,也是具有共性功能的方法描述

    • 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法

    • 一个具体方法:com.itheima.dao包下的BookDao接口中的无形参无返回值的save方法

    • 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法

  • 通知(Advice):若干个方法的共性功能,在切入点处执行,最终体现为一个方法

  • 切面(Aspect):描述通知与切入点的对应关系

  • 目标对象(Target):被代理的原始对象成为目标对象

切入点表达式 表达式标准格式
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
访问修饰符(描述通配符)

● 访问修饰符可以省略
● 返回值类型、包名、类名、方法名可以使用星号* 代表任意
● 包名与类名之间一个点 . 代表当前包下的类,两个点 … 表示当前包及其子包下的类
● 参数列表可以使用两个点 …表示任意个数,任意类型的参数列表

例如:

execution(public void com.itheima.aop.Target.method())
execution(void com.itheima.aop.Target.*(..))
execution(* com.itheima.aop.*.*(..))
execution(* com.itheima.aop..*.*(..))
execution(* *..*.*(..))
AOP切入点表达式书写技巧
  1. 所有代码按照标准规范开发,否则以下技巧全部失效;

  2. 描述切入点通常描述接口,而不描述实现类;

  3. 访问控制修饰符针对接口开发均采用public描述(可省略访问控制修饰符描述);

  4. 返回值类型对于增删改类使用精准类型加速匹配,对于查询类使用*通配快速描述;

  5. 包名书写尽量不使用…匹配,效率过低,常用*做单个包描述匹配,或精准匹配;

  6. 接口名/类名书写名称与模块相关的采用*匹配,

    例如UserService书写成*Service,绑定业务层接口名

  7. 方法名书写以动词进行精准匹配﹐名词采用*配﹐

    例如getByld书写成getBy*,selectAll书写成selectAll;

  8. 参数规则较为复杂,根据业务方法灵活调整;

  9. 通常不使用异常作为匹配规则。

基于注解的AOP开发 开发步骤

① 创建目标接口和目标类(内部有切点)
② 创建切面类(内部有增强方法)
③ 将目标类和切面类的对象创建权交给 spring
④ 在切面类中使用注解配置织入关系
⑤ 在配置文件中开启组件扫描和 AOP 的自动代理
⑥ 测试

代码实现

① 创建目标接口和目标类(内部有切点)

public interface TargetInterface {
    public void save();
}
public class Target implements TargetInterface {
    public void save() {
        System.out.println("save running.....");
    }
}

② 创建切面类(内部有增强方法)

public class MyAspect {
	//前置增强方法
    public void before(){
        System.out.println("前置增强..........");
    }
}

③ 将目标类和切面类的对象创建权交给 spring

@Component("target")
public class Target implements TargetInterface {
    public void save() {
        System.out.println("save running.....");
        //int i = 1/0;
    }
}
@Component("myAspect")
public class MyAspect {
    public void before(){
        System.out.println("前置增强..........");
    }
}

④ 在切面类中使用注解配置织入关系

@Component("myAspect")
@Aspect //标注当前MyAspect是一个切面类
public class MyAspect {
    //配置前置通知
    @Before("execution(* com.itheima.anno.*.*(..))")
    public void before(){
        System.out.println("前置增强..........");
    }
}

⑤ 在配置文件中开启组件扫描和 AOP 的自动代理






⑥ 测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-anno.xml")
public class AnnoTest {
    @Autowired
    private TargetInterface target;

    @Test
    public void test1(){
        target.save();
    }
}

⑦ 测试结果

前置增强..........
save running.....
注解配置AOP 注解通知类型
名称注解说明
前置通知@Before用于配置前置通知。指定增强的方法在切入点方法之前执行
后置通知@AfterReturning用于配置后置通知。指定增强的方法在切入点方法之后执行
环绕通知@Aronud用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
异常抛出通知@AfterThrowing用于配置异常抛出通知。指定增强的方法在出现异常时执行
最终通知@After用于配置最终通知。无论增强方式执行是否有异常都会执行
切点表达式的抽取

在切面内定义方法,在该方法上使用@Pointcut 注解定义切点表达式,然后在在增强注解中进行引用。具体如下:

@Component("myAspect")
@Aspect //标注当前MyAspect是一个切面类
public class MyAspect {
    //Proceeding JoinPoint:  正在执行的连接点===切点
    //@Around("execution(* com.itheima.anno.*.*(..))")
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前增强....");
        Object proceed = pjp.proceed();//切点方法
        System.out.println("环绕后增强....");
        return proceed;
    }

    //@After("execution(* com.itheima.anno.*.*(..))")
    @After("MyAspect.pointcut()")
    public void after(){
        System.out.println("最终增强..........");
    }

    //定义切点表达式
    @Pointcut("execution(* com.itheima.anno.*.*(..))")
    public void pointcut(){}
}
@Around注意事项

1.环绕通知必须依赖形参ProceedingloinP?oint才能实现对原始方法的调用﹐进而实现原始方法调用前后同时添加通知;

2.通知中如果未使用ProceedingJoinPoint对原始方法进行调用将跳过原始方法的执行;

3.对原始方法的调用可以不接收返回值,通知方法设置成void即可,如果接收返回值,必须设定为Object类型;

4.原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void,也可以设置成Ooject;

5.由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象。

Spring事务

事务作用:在数据层保障一系列的数据库操作同成功同失败。

Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败。

编程式事务控制相关对象 PlatformTransactionManager

Spring为了管理事务,提供了一个平台事务管理器PlatformTransactionManager:

方法说明
Transactionstatus getTransaction (TransactionDefination defination)获取事务的状态信息
void commit (Transactionstatus status)提交事务
void rollback (Transactionstatus status)回滚事务

注意:

PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,

例如:Dao 层技术是jdbc 或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager

Dao 层技术是hibernate时:org.springframework.orm.hibernate5.HibernateTransactionManager

TransactionDefinition

TransactionDefinition 是事务的定义信息对象,里面有如下方法:

方法说明
int getIsolationLevel()获得事务的隔离级别
int getPropogationBehavior ( )获得事务的传播行为
int getTimeout ()获得超时时间
boolean isReadOnly ()是否只读
TransactionStatus

TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。

方法说明
boolean hasSavepoint ()是否存储回滚点
boolean isCompleted ()事务是否完成
boolean isNewTransaction ()是否是新事务
boolean isRollbackonly ()事务是否回滚
事务角色

事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法。

事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法。

进行提交与回滚,事务(转账操作中:A钱-,B钱+)作为一个整体,一旦部分执行不成功,能够整个回滚,从而确保若:A-成功,B+失败后,A,B都将回滚,恢复原状态。

事务传播行为

事务传播行为:事务协调员对事务管理员所携带事务的处理态度。

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1016616.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号