初识Spring+AspectJ+spring之事务管理

一、初识Spring

 

1.Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架

EE的三层结构:web层、业务层、数据访问层(持久层,集成层)

2.Spring的核心:IOC(控制反转)、AOP(面向切面编程)

3.学习Spring需要的入门准备(①下载Spring开发包 ②创建web工程引入相应的jar包 ③创建Spring配置文件④在配置中配置类⑤创建测试类)

Spring的入门级案例:

1.创建一个接口

package org.llj.springdemo;
public interface  HelloService {
	public void sayHello();
}

2.创建该接口的实现类

public class HelloServiceImpl implements HelloService {
	private String info;
	public void setInfo(String info) {
		this.info = info;
	}
	@Override
	public void sayHello() {
		System.out.println("hello spring"+info);
	}
}

3.配置配置文件:



	
	
	
	
	

4.编写测试类:

public class ServiceTest {
	
	@Test
	//传统方式的测试
	public void demo1(){
		HelloService helloService=new HelloServiceImpl();
		helloService.sayHello();
	}
	@Test
	//采用spring框架测试
	public void demo2(){
		org.springframework.context.ApplicationContext applicationContext
		=new ClassPathXmlApplicationContext("applicationContext.xml");
		HelloService helloService=(HelloService) applicationContext.getBean("userService");
		helloService.sayHello();
	}
	@Test
	public void demo3(){
		org.springframework.context.ApplicationContext applicationContext
		=new FileSystemXmlApplicationContext("applicationContext.xml");
		HelloService helloService=(HelloService) applicationContext.getBean("userService");
		helloService.sayHello();
	}
}

4.DI:依赖注入:在Spring创建对象的过程中,把对象依赖的属性注入到类中.

5.IOC装配bean的方式(三种)

①构造方法实例化:

创建要实例化的类

package org.llj.springdemo2;
/**
 * 使用无参数的构造方法实例化
 * @author lenovo
 *
 */
public class bean1 {
}

加载配置文件


	

编写测试类

@Test
	public void demo1(){
		//1.加载类
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext
				("ApplicationContext.xml");
		bean1 bean1=(org.llj.springdemo2.bean1) applicationContext.getBean("bean1");
		System.out.println(bean1);
	}

②静态工厂实例化

package org.llj.springdemo2;
/**
 * 使用静态工厂实例化
 * @author lenovo
 *
 */
public class bean2 {
	
}
package org.llj.springdemo2;

public class bean2Factory {
	public static bean2 getBean2(){
		System.out.println("静态工厂实例化");
		return new bean2();
	}
}

加载配置文件:

 
	 

测试:

@Test
	public void demo2(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext
				("ApplicationContext.xml");
		bean2 bean2=(org.llj.springdemo2.bean2) applicationContext.getBean("bean2");
		System.out.println(bean2);
	}

③实例工厂实例化

package org.llj.springdemo2;
/**
 * 使用实例工厂的方法实例化
 * @author lenovo
 *
 */
public class bean3 {

}
package org.llj.springdemo2;
/**
 * 使用实例工厂实例化
 * @author lenovo
 *
 */
public class bean3Factory {
	public  bean3 getBean3(){
		System.out.println("实例工厂实例化");
		return new bean3();
	}
}

配置文件:


	 
	 

测试:

@Test
	public void demo3(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext
				("ApplicationContext.xml");
		bean3 bean3=(org.llj.springdemo2.bean3) applicationContext.getBean("bean3");
		System.out.println(bean3);
	}

6.bean中属性注入:

①构造器的方法注入:


	 
	 
	 
	  
	  
	  
	 

②setter方法注入:


	 property 标签中name就是属性名称,value就是属性值 ref表示引用的其他对象
	 	
	 	
	 
	 
	 

③名称空间p注入:


	  
 
 		 	
	 

④spel写法

 
	 value的#号后的大括号如果有单引号,说明是常量;如果没有单引号,说明是引用类型
	 	
	 	
	 

⑤集合注入


	 
	 	
	 		
	 			
	 			
	 		
	 	
	 	
	 	
	 		
	 			花花
	 			红军
	 		
	 	
	 	
	 	
	 		
	 			
	 			
	 		
	 	

⑥propeties注入:


	 		
	 			root
	 			123
	 		
	 	
	 

7.IOC注解方式装配bean

 

Spring的框架中提供了与@Component注解等效的三个注解:

@Repository 用于对DAO实现类进行标注

@Service 用于对Service实现类进行标注

@Controller 用于对Controller实现类进行标注

普通属性;

@Value(value="itcast")

private String info;

 对象属性:

@Autowired:自动装配默认使用类型注入.

@Autowired

  @Qualifier("userDao")       --- 按名称进行注入.

 @Autowired

    @Qualifier("userDao")      

private UserDao userDao;

等价于

@Resource(name="userDao")

       private UserDao userDao;

8.spring整合JUNIT测试

 

1.程序中有Junit环境.

2.导入一个jar包.spring与junit整合jar包.

* spring-test-3.2.0.RELEASE.jar

3.测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext2.xml")
public class springTest {
	@Autowired
	private UserService userservice;
	@Test
	public void demo1(){
		userservice.sayhello();
	}
}

二、spring中的AOP

AOP的底层实现:

1.JDK动态代理

public class JDKProxy implements InvocationHandler{
	private UserDao userDao;

	public JDKProxy(UserDao userDao) {
		super();
		this.userDao = userDao;
	}

	public UserDao createProxy(){
		//第一个参数为类装载器,第二个参数是真实类所拥有的接口,第三个数组则是当前类
		UserDao proxy=(UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
				userDao.getClass().getInterfaces(), this);
		return proxy;
	}

	//调用目标对象的任意一个方法,都相当于调用了Invoke方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		if("add".equals(method.getName())){
			//记录日志
			System.out.println("日志记录======================");
			//执行add方法
			Object result=method.invoke(userDao, args);
			return result;
		}else {
			return method.invoke(userDao, args);
		}
	
	}
}

2.CGLIB动态代理

public class CGLibProxy implements MethodInterceptor {
	private ProductDao productDao;

	public CGLibProxy(ProductDao productDao) {
		super();
		this.productDao = productDao;
	}
	
	public ProductDao createProxy(){
		//使用CGLib生成代理
		//1.创建核心类:Enhancer
		Enhancer enhancer=new Enhancer();
		//2.为其设置父类
		enhancer.setSuperclass(productDao.getClass());
		//3.设置回调
		enhancer.setCallback(this);
		//4.创建代理
		return (ProductDao) enhancer.create();
	}

	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		if("add".equals(method.getName())){
			System.out.println("日志记录=================");
			Object object=methodProxy.invokeSuper(proxy, args);
			return object;
		}
		return methodProxy.invokeSuper(proxy, args);
	}
}

Spring框架,如果类实现了接口,就使用JDK的动态代理生成代理对象,如果这个类没有实现任何接口,使用CGLIB生成代理对象.

Spring中AspectJ的支持

 

AspectJ增强:

@Before 前置通知,相当于BeforeAdvice

@AfterReturning 后置通知,相当于AfterReturningAdvice

@Around 环绕通知,相当于MethodInterceptor

@AfterThrowing抛出通知,相当于ThrowAdvice

@After 最终final通知,不管是否异常,该通知都会执行

@DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)

1.基于注解的


	
	
	
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 切面类,就是切点与增强的结合
 * @author lenovo
 *
 */
@Aspect
public class MyAspect {
	@Before("execution(* org.llj.spring.demo1.UserDao.add(..))")
	public void before(JoinPoint joinPoint){
		System.out.println("这是一个前置增强……"+joinPoint);
	}
	@AfterReturning(value="execution(* org.llj.spring.demo1.UserDao.delete(..))",returning="returnVal")
	public void after(Object returnVal){
		System.out.println("这是一个后置增强……"+returnVal);
	}
	@Around("MyAspect.mypointcut()")
	public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
		System.out.println("环绕前增强");
		Object obj=proceedingJoinPoint.proceed();
		System.out.println("环绕后增强");
		return obj;
	}
	@AfterThrowing(value="MyAspect.mypointcut()",throwing="e")
	public void throwing(Throwable e){
		System.out.println("不好了。出异常了"+e.getMessage());
	}
	@After("MyAspect.mypointcut()")
	public void after(){
		System.out.println("最终通知……");
	}
	@Pointcut("execution(* org.llj.spring.demo1.UserDao.find(..))")
	private void mypointcut(){
		
	}
}

二、基于XML的

package org.llj.spring.demo2;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectXML {
	public void before(){
		System.out.println("前置通知……");
	}
	public void aferReturning(Object returnVal){
		System.out.println("后置通知……"+returnVal);
	}
	//环绕通知
	public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
		System.out.println("环绕前通知……");
		Object result=proceedingJoinPoint.proceed();
		System.out.println("环绕后通知……");
		return result;
	}
	//异常通知
	public void afterThrowing(Throwable e){
		System.out.println("出异常了……"+e.getMessage());
	}
	//最终通知
	public void after(){
		System.out.println("这是最终通知……");
	}
}

	
	
	
	
	
	
	
		
		
		
			
			
			
			
			
			
			
			
			
			
		
	

Spring的jdbcTemplate

1.jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_day02
jdbc.user=root
jdbc.password=123

2.spring 提供了三种连接池(以下)

①.配置spring默认的连接池


		
		
		
		
	

②.配置dbcp连接池


		
		
		
		
	

③.-配置c3p0连接池 


		
		
		
		
	

3.定义jdbcTemplate摸板类


		
	
	
		
	

JdbcTemplate的CRUD的操作

import java.awt.List;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
/**
 * jdbcDaoSupport这个类中已经定义了模板,并且有一个set方法,所以这边继承JdbcDaoSupport之后就
 * 不需要在定义模板
 * @author lenovo
 *
 */
public class UserDao extends JdbcDaoSupport {
	

	public void add(User user){
		String sql="insert into user values(null,? )";
		this.getJdbcTemplate().update(sql,user.getName());
	}
	public void update(User user){
		String sql="update user set name = ? where id = ?";
		this.getJdbcTemplate().update(sql, user.getName(),user.getId());
	}
	public void delete(User user){
		String sql="delete from user where id = ?";
		this.getJdbcTemplate().update(sql, user.getId());
	}
	public String findNameById(int id){
		String sql="select name from user where id = ?";
		return this.getJdbcTemplate().queryForObject(sql, String.class, id);
	}
	public User findById(int id){
		String sql="select * from user where id = ?";
		User user=(User)this.getJdbcTemplate().queryForObject(sql, new UserRowMapper(),id);
		return user;
	}
	public java.util.List findAll(){
		String sql="select * from user";
		return this.getJdbcTemplate().query(sql, new UserRowMapper());
	}
	class UserRowMapper implements RowMapper{
		/**
		 * rs:结果集
		 * rowNum:行号
		 */
		@Override
		public User mapRow(ResultSet rs, int rowNum) throws SQLException {
			User user=new User();
			user.setId(rs.getInt("id"));
			user.setName(rs.getString("name"));
			return user;
		}
		
	}

}

测试方法:

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class springTest {
	@Autowired
	@Qualifier("userDao")
	private UserDao userDao;
	
	@Test
	public void demo1(){
		User user=new User();
		user.setName("娟儿");
		userDao.add(user);
	}
	@Test
	public void demo2(){
		User user=new User();
		user.setId(1);
		user.setName("珑珠");
		userDao.update(user);
	}
	@Test
	public void demo3(){
		User user=new User();
		user.setId(1);
		userDao.delete(user);
	}
	@Test
	public void demo4(){
		String name=userDao.findNameById(2);
		System.out.println(name);
	}
	@Test
	public void  demo5(){
		User user=userDao.findById(2);
		System.out.println(user);
	}
	@Test
	public void demo6(){
		List list=userDao.findAll();
		for (User user : list) {
			System.out.println(user);
		}
	}

}

 

三、Spring之事务管理

 

Spring的事务管理主要分成两类:

1.编程式事务管理(手动编写代码完成事务的管理)

2.声明式事务管理 (不需要手动编写,配置 )

事务操作的环境搭建:

1.需要有相应的数据库。

2.创建一个动态web项目:导入相应的jar;引入配置文件

3.创建类:XXXService;XXXDao

4.在Spring中注册业务层类和持久层类:


	
		
		
		
		
	
	
	
	
		
		
	

5.OK,编写测试类,测试环境是否搭建成功。

Spring的事务管理

不管哪种方式都需要事务管理器(TransactionManager)


	
		
		
	

一.手动编写的方式完成事务管理

1.注册事务模板:(TransactionTemplate)


	
		
	

2.在业务层注入模板类:(模板管理事务)


	
		
		
		
		
	
	

3.在业务层代码上使用模板:(以下是我的业务层代码)

package org.llj.spring.demo1;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	private TransactionTemplate transactionTemplate;
	
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}
	@Override
	public void transfer(final String from, final String to, final Double money) {
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {	
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				// TODO Auto-generated method stub
				accountDao.out(from, money);
				int i=10/0;
				accountDao.in(to, money);
			}
		});
	}

}
transactionTemplate.execute(new TransactionCallbackWithoutResult() {	
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				// TODO Auto-generated method stub
				accountDao.out(from, money);
				int i=10/0;
				accountDao.in(to, money);
			}
		});
	}

}

二.原始的声明式事务管理:

1.创建业务层代理对象(飘蓝的为属性设置,如果不写,则系统默认)


	
		
		
		
		
		
		
			
				PROPAGATION_REQUIRED
			
		
	PROPAGATION_REQUIRED
			
		
	

2.编写测试类(注意注入的是代理对象)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class springTest2 {
	@Autowired
	@Qualifier("accountServiceProxy")
	private AccountService accountService;
	
	@Test
	public void demo1(){
		accountService.transfer("aaa", "bbb", 100d);
	}

}"accountServiceProxy")
	private AccountService accountService;
	
	@Test
	public void demo1(){
		accountService.transfer("aaa", "bbb", 100d);
	}

}

三.声明式事务管理(基于切面)

1.导入所需的jar包,引入配置文件(aop、tx的约束)

2.事务管理(定义增强)


	
	
	
	
		
	
	

3.定义切点和通知


	
	
		
	
			
	

4.测试(不需要注入代理对象,注入service对象即可)

四.基于注解的事务管理

1.注解事务:


	

2.在service 上使用注解

@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	@Override
	public void transfer(String from,  String to,  Double money) {
				accountDao.out(from, money);
				//int i=10/0;
				accountDao.in(to, money);	
	}
}
public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	@Override
	public void transfer(String from,  String to,  Double money) {
				accountDao.out(from, money);
				//int i=10/0;
				accountDao.in(to, money);	
	}
}

以上为spring中的几种事务管理;其中手动编写的方式代码量大,代码具有入侵性

原始的声明式事务管理需要为每一个管理事务的类生成代理,需要为每个类都进行配置。

基于aspect的声明式事务管理是重点。

 

 

你可能感兴趣的:(javaweb)