Spring总结
1.问题:
Spring事务管理是怎么样的???
2.关于Spring:
目标:简化java开发。
核心是IOC容器。
核心思想:IOC(控制反转)和AOP(依赖注入)。让spring帮助我们管理bean对象
用法:日志打印、性能统计、异常处理。
MVC架构模式:
3.Spring的作用:
- Spring就是一个大工厂,管理业务对象;
- 贯穿表现层、业务层和持久层一站式的分层轻量级框架;是一种java2EE应用各层的解决方案;不是取代已有框架,而是整合各种已有框架;
- AOP编程的支持,用法:日志打印、性能统计、异常处理等。 面向切面编程。。
4.Spring体系结构:
- core container
- beans与core 它们提供spring框架最基本功能,包含ioc与di
- context 上下文对象,基于beans与cores
- spel它是spring提供的一个表达式语言
5.Spring框架优点
- 方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
- AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
- 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
- 方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
- 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:MyBatis、Quartz等)的直接支持
- 降低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在xml方式管理bean的jar包基础上导入aop的jar包
- 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>
- 3开启注解扫描:
<context:component-scan base-package="cn.it" />
这个配置作用是指定spring扫描的包,它包含了context:annotation-config的功能(让spring中常用的一些注解生效)
- 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管理中