Spring总结

1.问题:

Spring事务管理是怎么样的???

 

2.关于Spring:

目标:简化java开发。

核心是IOC容器。

核心思想:IOC(控制反转)和AOP(依赖注入)。让spring帮助我们管理bean对象

用法:日志打印、性能统计、异常处理。

 

MVC架构模式:

Spring总结

3.Spring的作用:

  1. Spring就是一个大工厂,管理业务对象;
  2. 贯穿表现层、业务层和持久层一站式的分层轻量级框架;是一种java2EE应用各层的解决方案;不是取代已有框架,而是整合各种已有框架;
  3. AOP编程的支持,用法:日志打印、性能统计、异常处理等。   面向切面编程。。

 

4.Spring体系结构:

Spring总结

  1. core container
    1. beans与core 它们提供spring框架最基本功能,包含ioc与di
    2. context 上下文对象,基于beans与cores
    3. spel它是spring提供的一个表达式语言

 

 

5.Spring框架优点

  1. 方便解耦,简化开发

Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理

  1. AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

  1. 声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无需手动编程

  1. 方便程序的测试

Spring对Junit4支持,可以通过注解方便的测试Spring程序

  1. 方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:MyBatis、Quartz等)的直接支持

  1. 降低JavaEE API的使用难度

Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

6、Spring管理Bean

1.1.springBean的获取与实例化-作用域scope

<bean id="userService" class="cn.itheima.ioc.UserServiceImpl" scope="singleton">
<property name="info" value="ITCAST"></property>
</bean>

在bean声明时它有一个scope属性,它是用于描述bean的作用域。

singleton:单例 代表在spring ioc容器中只有一个Bean实例 (默认的scope)

prototype多例 每一次从spring容器中获取时,都会返回一个新的实例

request 用在web开发中,将bean对象request.setAttribute()存储到request域中

session 用在web开发中,将bean对象session.setAttribute()存储到session域中

在开发中常用的值是singleton与prototype

 

1.2.springBean属性注入的属性注入方式

<!-- 使用setter方法对car的属性进行注入 -->

<bean id="car1" class="cn.it.di.Car">
<property name="name" value="宝马" />
<property name="price" value="500000" />
</bean>
<bean id="person" class="cn.it.di.Person">
<property name="name" value="张三" />
<property name="car" ref="car1" /><!-- ref引用其它bean的id或name值 -->
</bean>
@Test
public void test3() {
ApplicationContext applicationContext = 
new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) applicationContext.getBean("person");
System.out.println(person.getName() + "  " + person.getCar().getName());
}

7、注解开发

1.spring注解开发-bean注册

注解方式来管理bean步骤:

  1. 1在xml方式管理bean的jar包基础上导入aop的jar包

Spring总结

  1. 2引入context的名称空间
<?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"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">


</beans>
  1. 3开启注解扫描:
<context:component-scan base-package="cn.it" /> 

 这个配置作用是指定spring扫描的包,它包含了context:annotation-config的功能(让spring中常用的一些注解生效)

  1. 4.在需要被ioc(Spring管理)的类上配置@Component,
package cn.itheima.annotation;

public interface IUserService {

public void add();
}

package cn.it.annotation;

import org.springframework.stereotype.Component;

@Component("userService") //后面括号默认的名字类名的首字母小写
public class UserServiceImpl implements IUserService {
@Override
public void add() {
	 System.out.println("userService add..");
}
}


public class AnnotationTest {
@Test
public void test1() {
ApplicationContext context = 
new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService = (IUserService) context.getBean("userService");
userService.add();
}
}

在spring2.5后为@Component添加了三个衍生的注解

@Repository 用于DAO层

@Service 用于service层

@Controller  用于表现层

对于我们的bean所处在的位置可以选择上述三个注解来应用,如果你的bean不明确位置,就可以使用@Component.

 

2.spring注解开发-属性依赖注入

1、简单的属性注入

package cn.itheima.annotation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements IUserService {
	
@Value("张三")
private String name;

@Override
public void add() {
	 System.out.println("userService add.." + name);
}
}

2、复杂的属性注入

package cn.itheima.dao;

public interface IUserDAO {

public void add();
}

package cn.itheima.dao;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDAOImpl implements IUserDAO {

@Override
public void add() {
	System.out.println("userDao add...");
}
}

package cn.it.annotation;

@Service("userService")
public class UserServiceImpl implements IUserService {
	
@Value("张三")
private String name;

@Autowired
private IUserDAO userDao;

@Override
public void add() {
// System.out.println("userService add.." + name);
userDao.add();
}
}

public class AnnotationTest {
@Test
public void test1() {
ApplicationContext context = 
new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService = (IUserService) context.getBean("userService");
userService.add();
}}

注意:@Value @Autowired它们可以修饰属性,也可以修饰setter方法,如果写在属性上,就不需要提供setter方法。

3.spring注解开发-属性依赖注入指定注入的名称

1.1、按照类型注入

package cn.itheima.annotation;
@Service("userService")
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDAO userDao;

@Override
public void add() {
	 
	userDao.add();
}
}
package cn.itheima.annotation;
@Service("userService")
public class UserServiceImpl implements IUserService {
@Resource
private IUserDAO userDao;

@Override
public void add() {
	  userDao.add();
}
}

1.2、按照名称注入

package cn.it.annotation;
@Service("userService")
public class UserServiceImpl implements IUserService {
	
@Autowired
@Qualifier("userDao")
private IUserDAO userDao;

@Override
public void add() {
userDao.add();
}
}
package cn.itheima.annotation;

@Service("userService")
public class UserServiceImpl implements IUserService {
@Resource(name="userDao")
private IUserDAO userDao;

@Override
public void add() {
	 userDao.add();
}
}

4.spring注解开发-其它注解

@Service("userService")
@Scope("prototype")
public class UserServiceImpl implements IUserService {
public UserServiceImpl() {
		System.out.println("构造了UserServiceImpl对象");
}

@PostConstruct
public void mInit() {
		
System.out.println("Bean初始化");
}
@PreDestroy
public void mDestroy() {
		
System.out.println("Bean销毁");
}
}

@Scope("prototype")@Scope它以描述bean的作用域

@PostConstruct相当于init-method=”mInit

 

8.注解方式实现AOP(...)

学习:https://www.cnblogs.com/hongwz/p/5764917.html

1.springAOP编程-aspectJ注解开发-前置通知

第一步:把通知和目标纳入Spring的管理当中:

开启注解扫描<context:component-scan base-package="cn.ith"/>

在通知和目标类上配置@Component

第二步:定义目标

package cn.it.aspectj_annotation;

import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements ICustomerService {
	@Override
	public void save() {
		System.out.println("customerService  save...");
	}
	@Override
	public void search() {
		//System.out.println(10/0);
		System.out.println("customerService  search...");
	}
	@Override
	public int update() {

		System.out.println("customerService  update...");
		return 10;
	}
}

第三步:定义切面

@Component
@Aspect
public class CustomerServiceHelper {

// 前置通知
@Before("execution(* *.save(..))")
public void before() {
	   System.out.println("前置通知...");
}
}

使用@Aspect来声明切面

使用@Before来声明前置通知

第四步:开启aspectj注解的自动代理<aop:aspectj-autoproxy/>

第五步:测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AspectAnnotationTest {

	@Autowired
	private ICustomerService customerService;

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

 

2.springAOP编程-aspectJ注解开发-其他通知

后置通知

// 后置通知
@AfterReturning(value = "execution(* *.update(..))", returning = "value")
public void afterReturning(Object value) {
	System.out.println("后置通知,目标方法的返回是" + value);
}

环绕通知

// 环绕通知
@Around("execution(* *.s*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
	System.out.println("环绕前...");
	Object value = pjp.proceed();
	System.out.println("环绕后");
	return value;
}

异常通知

// 异常抛出通知
@AfterThrowing(value="execution(* *.s*(..))", throwing="tx")
public void afterThrowing(Throwable tx) {
	System.out.println("异常抛出通知:" + tx);
}
最终通知
@After("execution(* *.s*(..))")
public void after() {
	System.out.println("最终通知");
}

3.springAOP编程-aspectJ注解开发(@Pointcut声明切点)

在每一个通知中定义切点,工作量大,不方便维护,可以使用@Pointcut来声明切点

@Component
@Aspect
public class CustomerServiceHelper {

// 定义切点
	@Pointcut("execution(* *.s*(..))")
	private void mypointcut() {
	}

	@Pointcut("execution(* *.update(..))")
	private void mypointcut1() {
	}

	// 使用上面定义的切点
	@Before("mypointcut()||mypointcut1()")
	public void before() {
		System.out.println("前置通知...");
	}

	// 使用上面定义的切点
	@After("mypointcut()")
	public void after() {
		System.out.println("最终通知");
	}
}

切点允许逻辑运算例如mypointcut()||mypointcut1

4.springAOP编程-aspectJ注解开发(选择代理方式)

始终使用cglib代理:

<aop:aspectj-autoproxy proxy-target-class="true"/>

 

9.声明式事务管理

声明式事务控制,基于AOP对目标进行代理,添加around环绕通知。这种方案,它不具有侵入性,不需要修改原来的业务代码。

spring事务管理-基于annotation声明式事务管理

1.配置事务管理器

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="c3p0DataSource"/>
</bean>

2. 开启注解事务

<tx:annotation-driven transaction-manager="transactionManager"/>

3.方法或者类上配置事务@Transactional

@Transactional
@Override
public void account(String outname, String inname, double money) {
// 从outname转出money
accountDao.accountOut(outname, money);
int a = 10 / 0; // 一定会抛出异常
// 向inname转入money
accountDao.accountIn(inname, money);
}

 

******

IOC和DI区别?  

 DI:dependency injection 依赖注入    

1.IOC: Spring统一管理应用程序运行时所需要的资源

2. DI :应用程序运行时所需要的资源由Spring来提供

3. 站在Spring的角度就是IOC, 站在应用程序的角度就是DI, IOC是DI的前提

4. 应用程序能够DI注入的前提是:所注入资源要在Spring的管理中; 自己也要在Spring管理中