Spring学习笔记01

学习了Spring之后,一直没有总结,总感觉差点东西,以下仅代表个人观点

1.Spring的理解

Spring是一对象的容器

2.Spring注入对象

2.1空参构造注入

<bean name="名称" class="注入对象全路径"  scope="scope属性" Init-method="初始化方法" destroy-method="销毁方法">
</bean>

2.1.1scope属性

         singleton(默认值):单例对象,在spring容器中智慧存在一个实例

         prototype:多例原型,每次获得都重新创建(action要配置成多例)

         request:web环境下,与request生命周期一致

         session:web环境下,与session生命周期一致

2.1.2 生命周期

         Init-method配置初始化方法,spring会在对象创建之后立即调用

         destroy-method配置销毁方法,spring会在关闭销毁钱调用

2.2注解注入

开启注解扫描

<context:component-scan base-package="com.xxx.bean"/>

2.2.1注解创建对象(加载类上)

@Component("user")//通用
@Service("user")//service业务层
@Controller("user")//web层
@Repository("user")//仓库,dao层

2.2.2注解加入范围

@Scope(scopeName="prototype") //单例或多例

2.2.3注解注入属性

@Value("tom")//注入属性,建议加在set方法上

2.2.4注解注入对象

@Autowired//自动装配(问题:如果有多个同类对象,无法选择注入哪个)

@Qualifier("car2")//解决办法1在添加一个



@Resource(name="car2")//解决办法2使用手动注解

2.2.5注解初始化与销毁方法

@PostConstruct // 在构造后调用

@PreDestroy // 在销毁前调用,仅单例模式可用

3.Spring IOC&DI

IOC: Inverse Of Control 反转控制 将对象的创建权限交给Spring

DI: Dependency injection 依赖注入

实现IOC思想需要DI做支持:

注入方式:Set方法注入,构造方法注入,字段注入

注入类型:值类型注入(8大基本数据类型)、引用类型注入(将依赖对象注入

 

4.Spring AOP

4.1AOP思想

面向切面编程,纵向重复,横向抽取

例子:过滤器、拦截器、动态代理

 

4.2 Spring AOP(动态代理,cglib)

1)动态代理(优先)

被代理对象必须实现接口,否则就不行

2)cglib代理(无法使用动态代理就用动态代理)

可以对任何类生成代理(原理:对目标对象进行集成代理,所以不能被final修饰)

总结:

1通过动态代理可以体现AOP思想,但是AOP并不仅仅指动态代理

2对目标对象中的方法进行增强

3为容器中管理的对象生成动态代理对象

4Spring封装了动态代理与cglib,我们只需要调用,可以对任何类进行代理增强

 

4.3 AOP名词(行话)

1)Joinpoint(连接点):目标对象中可以增强的方法
2)Pointcut(切入点):目标对象中已经增强的方法
3)Advice(通知/增强):用来增强目标对象的代码
4)Target(目标对象):被代理对象,就是目标对象
5)Weaving(织入):将通知(Advice)应用到切入点(Pointcut)的过程,生成代理对象的过程叫织入
6)Proxy(代理):将通知织入到目标对象后,形成代理对象
7)Aspect(切面):切入点+通知(增强后的内容)

 

4.4 Spring AOP到底如何用?

4.4.1xml配置

1 让spring帮生成代理对象,需要准备目标对象Target

<bean name="userService" class="com.tang.service.UserServiceImpl" />

2 给目标对象准备通知Advice

<bean name="myAdvice" class="com.tang.d_aop.MyAdvice" />

3 配置进行织入,将通知织入目标对象Weaving

Pointcut配置:

id:切点名称,取名任意

expression=""  切点覆盖范围(要增强谁?)
           1) execution("public void com.tang.service.UserServiceImpl.save()") =>全称
           2) execution("void com.tang.service.UserServiceImpl.save()")        =>返回类型省略
           3) execution("* com.tang.service.UserServiceImpl.save()")           =>对返回值不要求
           4) execution("* com.tang.service.UserServiceImpl.*()")              =>对方法不要求
           5) execution("* com.tang.service.UserServiceImpl.*(..)")            =>对方法的参数不要求
           6) execution("* com.tang.service.*ServiceImpl.*(..)")               =>对service不要求
           7) execution("* com.tang.service..*ServiceImpl.*(..)")              =>对子包也扫描
<aop:config>
	<aop:pointcut expression="execution(* com.tang.service.*ServiceImpl.*(..))"  id="pc" />
	<!-- 配置切面Aspect ref:通知对象的名称-->
	<aop:aspect ref="myAdvice">
		<!-- 前置通知 -->
		<aop:before method="before" pointcut-ref="pc"/>
		<!-- 后置通知 -->
		<aop:after-returning method="afterReturning" pointcut-ref="pc"/>
		<!-- 换绕通知 -->
		<aop:around method="around" pointcut-ref="pc"/>
		<!-- 异常通知 -->
		<aop:after-throwing method="afterException" pointcut-ref="pc"/>
		<!-- 后置通知 -->
		<aop:after method="after" pointcut-ref="pc"/>
	</aop:aspect>
</aop:config>

 

4.4.2注解配置

1.在通知包class前写

@Aspect

2.抽取切点,在通知包类内写

@Pointcut(value="execution(* com.tang.service.*ServiceImpl.*(..))")

public void pc(){}

3.配置织入,将通知包内方法前赋值属性

// 前置通知

@Before(value="MyAdvice.pc()")

// 返回后后置通知(方法没有异常时调用)

@AfterReturning(value="execution(* com.tang.service.*ServiceImpl.*(..))")

// 环绕通知

@Around(value="execution(* com.tang.service.*ServiceImpl.*(..))")

// 异常拦截通知

@AfterThrowing(value="execution(* com.tang.service.*ServiceImpl.*(..))")

// 后置通知(无论如何都要调用)

@After(value="execution(* com.tang.service.*ServiceImpl.*(..))")

 

5.Spring整合Junit测试

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.xxx.User;

@RunWith(SpringJUnit4ClassRunner.class) // 注入JUnit
@ContextConfiguration("classpath:applicationContext.xml") // 注入容器
public class Demo {
	
	@Resource(name="user")//将user对象注入u
	private User u;

	@Test
	// 空参构造
	public void testSpringJunit() throws Exception {
		System.out.println(u);
	}

}

6.Spring事务

6.1 事务

6.1.1事务并发问题

1)脏读
2)幻读
3)不可重复读

6.2.2事务隔离级别(解决并发问题)

1)1读未提交
2)2读已提交
3)4可重复读
4)8串行化

6.2 Spring事务管理

6.2.1接口

​​​​​​1)提供PlaformTransactionManager接口,针对不同平台实现不同实现类

DataSourceTransactionManager

HibernateTransactionManager

2)可选配置

事务隔离级别1 2 4 8

是否只读true(只读)false(可操作的)

事务的传播行为(解决业务方法之间平行调用时,事务处理方式问题)

PROPAGATION_REQUIRED          支持当前事务,如果不存在,就新建(默认)
PROPAGATION_SUPPORTS          支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY         支持当前事务,如果不存在,抛出异常

PROPAGATION_REQUIRES_NEW     必须开一个新的事务
PROPAGATION_NOT_SUPPORTED    如果有事务,就挂起事务,无事务执行
PROPAGATION_NEVER            永远不用事务
PROPAGATION_NESTED           如果有,就在开一个事务

 

猜你喜欢

转载自blog.csdn.net/qq_26786441/article/details/89084588
今日推荐