Spring

学习了Spring之后,一直没有总结,总感觉差点东西,以下仅代表个人观点,如有错误,还请指正。

目录

1.Spring的理解

2.Spring IOC&DI

2.1空参构造注入

2.2注解注入

3.Spring AOP

3.1AOP思想

3.2 Spring AOP(动态代理,cglib)

3.3 AOP名词

3.4 Spring AOP使用方法

4.Spring事务

4.1 事务

4.2 Spring事务管理

5.Spring整合Junit测试 


1.Spring的理解

Spring是一对象的容器,包含IOC与AOP两大核心内容

 

2.Spring IOC&DI

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

DI: Dependency injection 依赖注入

实现IOC思想需要DI做支持:
    注入方式:Set方法注入,构造方法注入,字段注入
    注入类型:值类型注入(8大基本数据类型)、引用类型注入(将依赖对象注入)

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方法上
public void setName(String name) {
	this.name = name;
}

2.2.4注解注入对象

@Autowired//自动装配(问题:如果有多个同类对象,无法选择注入哪个)
@Qualifier("car2")//解决办法1在添加一个

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

2.2.5注解初始化与销毁方法

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

 

3.Spring AOP

3.1AOP思想

面向切面编程,纵向重复,横向抽取
例子:过滤器、拦截器、动态代理

 

3.2 Spring AOP(动态代理,cglib)

1)动态代理(优先)

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

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

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

总结:

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

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

 

3.3 AOP名词

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

 

3.4 Spring AOP使用方法

4.4.1xml配置

1 准备目标对象(Target)

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

2 准备通知(Advice)

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

3 将通知(Advice)织入(Weaving)目标对象(Target)

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>

 

3.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.*(..))")

4.例子

//注解通知配置
@Aspect
public class MyAdvice {
	
	//抽取切点
	@Pointcut(value="execution(* com.tang.service.*ServiceImpl.*(..))")
	public void pc(){}

	@Before(value="MyAdvice.pc()")
        // 前置通知
	public void before() {
		System.out.println("这是前置通知");
	}

	@AfterReturning(value="execution(* com.tang.service.*ServiceImpl.*(..))")
	// 后置通知(方法没有异常时调用)
	public void afterReturning() {
		System.out.println("这是后置通知(方法没有出现异常)");
	}

}

4.Spring事务

4.1 事务

4.1.1事务并发问题

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

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

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

4.2 Spring事务管理

4.2.1接口

​​​​​​事务核心管理器,提供PlaformTransactionManager接口,针对不同平台实现不同实现类

//DBUtils、JDBC使用
DataSourceTransactionManager

//Hibernate使用
HibernateTransactionManager
//数据源
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
	<property name="driverClass" value="${jdbc.driverClass}"></property>
	<property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>
//核心事务管理控制器
<bean name="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>
//事务模板对象
<bean name="transactionTemplate"
	class="org.springframework.transaction.support.TransactionTemplate">
	<property name="transactionManager" ref="transactionManager"></property>
</bean>

4.2.2xml配置事务

isolation:事务隔离级别1 2 4 8

read-only:是否只读true(只读)false(可操作的)

propagation:事务的传播行为(解决业务方法之间平行调用时,事务处理方式问题)
    PROPAGATION_REQUIRED          支持当前事务,如果不存在,就新建(默认)
    PROPAGATION_SUPPORTS          支持当前事务,如果不存在,就不使用事务
    PROPAGATION_MANDATORY         支持当前事务,如果不存在,抛出异常
    PROPAGATION_REQUIRES_NEW     必须开一个新的事务
    PROPAGATION_NOT_SUPPORTED    如果有事务,就挂起事务,无事务执行
    PROPAGATION_NEVER            永远不用事务
    PROPAGATION_NESTED           如果有,就在开一个事务
//事务通知
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
		<tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
		<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
		<tx:method name="transfet" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
	</tx:attributes>
</tx:advice>
	
<!-- 配置织入 -->
<aop:config>
	<aop:pointcut expression="execution(* com.tang.service.*ServiceImpl.*(..))" id="txPc"/>
	<!-- 配置切面 :通知 切点-->
	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>

4.2.3注解配置事务

<!-- xml中开启注解管理 -->
<tx:annotation-driven/>
//代码中示例
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = true)
public class AccountServiceImpl implements AccountService {

    @Resource(name="accountDao")
    private AccountDao accountDao;
    
    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation=Propagation.REQUIRED, readOnly = false)
    public void transfet(Integer from, Integer to, Double money) {
        accountDao.decreaseMoney(from, money);
        accountDao.increaseMoney(to, money) > 0);
    }

}

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);
	}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值