一 spring常用的三种注入方式(setter方法注入,构造器注入,自动装配)
1 setter方法注入,在类中一定要写属性的setter方法。
1 <bean id="helloword" class="com.wengde.spring.bean.HelloWord"> 2 <property name="name2" value="wangwu"></property> 3 </bean>
1 <bean id="person" class="com.wengde.spring.bean.Person" scope="singleton"> 2 <property name="name" value="zhangsan"></property> 3 <property name="age" value="26"></property> 4 <property name="car" ref="car2"></property> 5 </bean>
id是bean的名字,具有唯一性,在同一个xml文件中id名字不能重复,class是全类名,所以必须要有无参构造器。name是类的属性名,也就是要和类的属性名一致。通过scope(singleton,prototype,request,session)来决定bean的作用域。通过ref来映射其他的bean。
2 构造器注入
1 <bean id="car" class="com.wengde.spring.bean.Car"> 2 <constructor-arg value="Baoma" index="0"></constructor-arg> 3 <constructor-arg value="red" index="1"></constructor-arg> 4 <constructor-arg value="3000" type="double"></constructor-arg> 5 </bean>
如果出现构造器参数个数一样的重载构造器,可以通过type来区分构造器参数的类型。
3 自动装配,通过注解@
1 public class TestBean12 { 2 @Autowired //字段注入 3 private String message; 4 //省略getter和setter 5 }
二、依赖注入——自动装配
在应用中,我们常常使用<ref>标签为JavaBean注入它依赖的对象,同时也Spring为我们提供了一个自动装配的机制,在定义Bean时,<bean>标签有一个autowire属性,我们可以通过指定它来让容器为受管JavaBean自动注入依赖对象。
自动装配是在配置文件中实现的,如下:<bean id="***" class="***" autowire="byType">
1.byName:按名称装配 可以根据属性的名称在容器中查询与该属性名称相同的bean,也就是bean的id值要和类的属性名称一致,如果没有找到,则属性值为null。假设Person类中有一个名为car和address的属性,如果容器中刚好有一个名为car和adress的Bean,Spring就会自动将其装配给Boss的car属性。
1 <bean id="address" class="com.wengde.spring.autowire.Address"> 2 <property name="city" value="shenzhen"></property> 3 <property name="street" value="huangnikan"></property> 4 </bean> 5 <bean id="car" class="com.wengde.spring.autowire.Car" > 6 <property name="pingpa" value="baoma"></property> 7 <property name="price" value="300000"></property> 8 </bean> 9 <bean id="person" class="com.wengde.spring.autowire.Person" autowire="byName"> 10 <property name="name" value="lijing"></property> 11 </bean>
2.byType:按类型装配 可以根据属性类型,在容器中寻找该类型匹配的bean,如有多个,则会抛出异常,如果没有找到,则属性值为null。假设Boss类中有一个Car类型的属性,如果容器中刚好有一个Car类型的Bean,Spring就会自动将其装配给Boss的这个属性。
根据属性Property的数据类型自动装配,这种情况,Customer设置了autowire="byType",Spring会总动寻找与属性类型相同的bean,找到后,通过调用setPerson(Person person)将其注入。
1 <bean id="customer" class="com.lei.common.Customer" autowire="byType" /> 2 <bean id="person" class="com.lei.common.Person" />
如果配置文件中有两个类型相同的bean会怎样呢?如下:
1 <bean id="customer" class="com.lei.common.Customer" autowire="byType" /> 2 <bean id="person" class="com.lei.common.Person" /> 3 <bean id="person_another" class="com.lei.common.Person" />
一旦配置如上,有两种相同数据类型的bean被配置,将抛出UnsatisfiedDependencyException异常,见以下:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException:
所以,一旦选择了“byType”类型的自动装配,请确认你的配置文件中每个数据类型定义一个唯一的bean。
三 集合参数注入
list集合
1 <bean id="personlist" class="com.wengde.spring.bean.Personlist"> 2 <property name="name" value="ligaojing" ></property> 3 <property name="age" value="30"></property> 4 <property name="car" > 5 <list> 6 <ref bean="car"/> 7 <ref bean="car2"/> 8 </list> 9 </property> 10 </bean>
1 <!-- 注入List类型属性 --> 2 <bean id="boss" class="com.spring.model.Boss"> 3 <property name="favorites"> 4 <list> 5 <value>看报</value> 6 <value>赛车</value> 7 <value>高尔夫</value> 8 </list> 9 </propert
set集合
1 <bean id=”……” class=”……”> 2 <property name="……"> 3 <set> 4 <value>value1</value> 5 <value>value2</value> 6 …… 7 </set> 8 </property> 9 </bean>
map集合:需要使用<map>标签来配置注入,其属性“key-type”和“value-type”分别指定“键”和“值”的数据类型。
1 <bean id="boss1" class="com.spring.model.Boss"> 2 <property name="jobs"> 3 <map> 4 <entry key="AM" value="会见客户" /> 5 <entry key="PM" value="公司内部会议" /> 6 </map> 7 </property> 8 </bean>
Properties:需要使用<props>标签来配置注入,键和值类型必须是String,不能变,子标签<prop key=”键”>值</prop>来指定键值对。
1 <!-- 注入Properties类型属性 --> 2 <bean id="boss2" class="com.spring.model.Boss"> 3 <property name="mails"> 4 <props> 5 <prop key="jobMail">john-office@163.com</prop> 6 <prop key="lifeMail">john-life@163.com</prop> 7 </props> 8 </property> 9 </bean>
四 静态工厂和实例工厂的配置
静态工厂的配置
1 package com.wengde.spring.factory; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 //静态工厂方法,在bean里应用了facotry-method,spring就不会创建当前的对象了,只调用了一个工厂方法,没有实例化对象,也就是没有调用构造方法 6 public class staticFactory { 7 public staticFactory(){ 8 System.out.println(12); 9 } 10 private static Map<String ,Car> cars=new HashMap<String , Car>(); 11 static{ 12 cars.put("audi", new Car("audi",30000)); 13 cars.put("baoma", new Car("baoma",40000)); 14 } 15 public static Car getcar(String name){ 16 return cars.get(name); 17 } 18 19 }
配置bean
1 <bean id="car1" class="com.wengde.spring.factory.staticFactory" factory-method="getcar"> 2 <constructor-arg value="baoma"></constructor-arg>//这个是工厂方法getcar()的参数 3 </bean>
非静态工厂的配置
1 package com.wengde.spring.factory; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public class InstanceCar { 7 private Map<String,Car> cars=null; 8 public InstanceCar(){ 9 System.out.println(2); 10 cars=new HashMap<String, Car>(); 11 cars.put("audi", new Car("audi",300000)); 12 cars.put("baoma", new Car("baoma",400000)); 13 14 } 15 public Car getcar(String name){ 16 return cars.get(name); 17 } 21 }
由于是非静态的,所以必须要先有一个实例对象了才可以调用其方法
1 <!-- 配置工厂的实例 --> 2 <bean id="carfactory" class="com.wengde.spring.factory.InstanceCar" > </bean> 3 <!-- 通过实例方法来配置bean --> 4 <bean id="car2" factory-bean="carfactory" factory-method="getcar"> 5 <constructor-arg value="audi"></constructor-arg>//工厂方法的参数 6 </bean>
五 基于注解的方式
扫描配置:自动扫描,多个包用逗号隔开,如果某个类的头上带有特定的注解[@Component/@Repository/@Service/@Controller],就会将这个对象作为Bean注册进Spring容器。
<context:component-scan base-package="com.wengde.spring.annotation,com...."></context:component-scan>
1 <!--context: exclude-filter 排除指定资源 --> 2 <!--<context:component-scan base-package="com.wengde.spring.annotation"> 3 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> 4 </context:component-scan>-->
1 <!-- <context:include-filter,只包含指定资源,需要use-default-filters="false"取消默认的filter,只使用指定的资源 --> 2 <!-- <context:component-scan base-package="com.wengde.spring.annotation" use-default-filters="false"> 3 <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> 4 </context:component-scan>-->
1 <!--assignable 按照类来 --> 2 <!-- <context:component-scan base-package="com.wengde.spring.annotation" > 3 <context:exclude-filter type="assignable" expression="com.wengde.spring.annotation.repository.UseRepository"/> 4 </context:component-scan> -->
在类的头上带有这些注解@Component/@Repository/@Service/@Controller时,可以通过类名首字母小写的类名要获取IOC对象
1 package com.wengde.spring.annotation.controller; 2 import org.springframework.beans.factory.annotation.Autowired; 3 import org.springframework.stereotype.Controller; 4 import com.wengde.spring.annotation.service.UserService; 5 @Controller 6 public class UserController { 7 private UserService userService; 8 @Autowired 9 public void setUserService(UserService userService) { 10 this.userService = userService; 11 } 12 public void execute(){ 13 System.out.println("UserController execute"); 14 userService.add(); 15 } 16 }
获取bean对象
1 ApplicationContext api=new ClassPathXmlApplicationContext("beans-annotations.xml"); 2 UserController userController=(UserController) api.getBean("userController");类名的首字母小写 3 userController.execute();
类的属性自动生成实例对象,通过在属性顶部加上@Autowired(required=false),require=false是取消自动生成实例对象
1 package com.wengde.spring.annotation.repository; 2 import org.springframework.beans.factory.annotation.Autowired; 3 import org.springframework.stereotype.Repository; 4 import com.wengde.spring.annotation.TestObject; 5 @Repository 6 public class UserRepositoryImpl implements UseRepository{ 7 @Autowired(required=false) 8 private TestObject testObject; 9 @Override 10 public void save() { 11 System.out.println("UserRepository Save..."); 12 System.out.println(testObject); 13 } 14 15 }
当一个接口有多个实现类的时候,为了指定是那个特定的实现类的对象,可以通过@Qualifier("userRepositoryImpl")注解来指定对应的实现类对象
1 package com.wengde.spring.annotation.service; 2 import org.springframework.beans.factory.annotation.Autowired; 3 import org.springframework.beans.factory.annotation.Qualifier; 4 import org.springframework.stereotype.Service; 5 import com.wengde.spring.annotation.repository.UseRepository; 6 import com.wengde.spring.annotation.repository.UserRepositoryImpl; 7 @Service 8 public class UserService { 9 @Autowired 10 @Qualifier("userRepositoryImpl") 11 private UseRepository useRepository; 12 public void add(){ 13 System.out.println("UserService add"); 14 useRepository.save(); 15 } 16 }
六 spring的AOP
动态代理
1 package com.wengde.spring.aop; 2 public interface ArithmeticCalculator { 3 int add(int i,int j); 4 int sub(int i,int j); 5 int div(int i,int j); 6 }
ArithmeticCalculator实现类
1 package com.wengde.spring.aop; 2 3 public class ArithmeticCalulatorImpl implements ArithmeticCalculator{ 4 5 @Override 6 public int add(int i, int j) { 7 int reslut=i+j; 8 return reslut; 9 } 10 11 @Override 12 public int sub(int i, int j) { 13 int reslut=i-j; 14 return reslut; 15 } 16 17 @Override 18 public int div(int i, int j) { 19 int reslut=i/j; 20 return reslut; 21 } 22 23 }
代理对象
1 package com.wengde.spring.aop; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.util.Arrays; 6 public class ArithmeticalCalculatorLoggingProxy { 7 //要代理的对象 8 private ArithmeticCalculator target; 9 //通过方法返回代理的对象 10 public ArithmeticalCalculatorLoggingProxy(ArithmeticCalculator target) { 11 super(); 12 this.target = target; 13 } 14 15 // 16 public ArithmeticCalculator getLoggingProxy(){ 17 ArithmeticCalculator proxy=null; 18 //代理对象由哪一个类加载器负责加载 19 ClassLoader loader=target.getClass().getClassLoader(); 20 //代理对象的类型,及其中有哪些方法 21 Class[] interfaces=new Class[]{ArithmeticCalculator.class}; 22 //当调用代理对象其中的方法时,该执行的代码 23 InvocationHandler h=new InvocationHandler() { 24 /* 25 * proxy;正在返回的那个代理对象,一般情况下,在invoke方法中都不使用该对象 26 * method:正在被调用的方法 27 * args:调用方法时传入的参数 28 * */ 29 @Override 30 public Object invoke(Object proxy, Method method, Object[] args) 31 throws Throwable { 32 //System.out.println(proxy.toString()); 33 String methodName=method.getName(); 34 //日志,前置通知 35 System.out.println("The method" +methodName+" begin with["+Arrays.asList(args)+"]"); 36 //执行方法 37 Object result=null; 38 try { 39 //返回通知 40 result=method.invoke(target, args); 41 } catch (Exception e) { 42 // TODO Auto-generated catch block 43 e.printStackTrace(); 44 //异常通知 45 } 46 //后置通知 47 System.out.println("The method" +methodName+" end with"+result); 48 return result; 49 } 50 }; 51 proxy=(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); 52 return proxy; 53 54 } 55 }
main方法
1 package com.wengde.spring.aop; 2 3 public class Main { 4 public static void main(String[] args) { 5 // ArithmeticCalculator arithmeticCalculator=new ArithmeticCalulatorImpl(); 6 ArithmeticCalculator target=new ArithmeticCalulatorImpl(); 7 ArithmeticCalculator proxy=new ArithmeticalCalculatorLoggingProxy(target).getLoggingProxy(); 8 System.out.println(proxy.getClass().getName());//代理 9 int result= proxy.add(2, 3); 10 System.out.println(result); 11 int result1= proxy.sub(6, 2); 12 System.out.println(result1); 14 } 16 }
Spring的AOP(基于注解),一些常用的术语
Aspect:切面
Advice:通知
Target:目标
Proxy:代理
Joinpoint:连接点
PointCut:切点
@Before:前置通知
@After:后置通知
@AfterReturning:返回通知
@AfterThrowing:异常通知
@Around:环绕通知
@Order:切面优先级,值越小,优先级越高
用代码要实现AOP
1 package com.wengde.spring.aop; 2 3 public interface ArithmeticCalculator { 4 int add(int i,int j); 5 int sub(int i,int j); 6 int div(int i,int j); 7 void delete(int i,int j); 8 9 }
1 package com.wengde.spring.aop; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class ArithmeticCalulatorImpl implements ArithmeticCalculator{ 7 8 @Override 9 public int add(int i, int j) { 10 int reslut=i+j; 11 return reslut; 12 } 13 14 @Override 15 public int sub(int i, int j) { 16 int reslut=i-j; 17 return reslut; 18 } 19 20 @Override 21 public int div(int i, int j) { 22 int reslut=i/j; 23 return reslut; 24 } 25 26 @Override 27 public void delete(int i, int j) { 28 System.out.println(i-j); 29 30 } 31 32 }
1 package com.wengde.spring.aop; 2 3 4 import java.util.Arrays; 5 import java.util.List; 6 7 import org.aspectj.lang.JoinPoint; 8 import org.aspectj.lang.ProceedingJoinPoint; 9 import org.aspectj.lang.annotation.After; 10 import org.aspectj.lang.annotation.AfterReturning; 11 import org.aspectj.lang.annotation.AfterThrowing; 12 import org.aspectj.lang.annotation.Around; 13 import org.aspectj.lang.annotation.Aspect; 14 import org.aspectj.lang.annotation.Before; 15 import org.aspectj.lang.annotation.Pointcut; 16 import org.springframework.core.annotation.Order; 17 import org.springframework.stereotype.Component; 18 19 @Component 20 @Aspect 21 @Order(1) 22 public class LoggingAspect { 23 /*定义一个方法,用于声明切点表达式,一般地,该方法中不在需要添如其他的代码 24 * 使用@pointcut来声明切入点表达式 25 * 后面的其他通知直接使用方法名来引用当前的切入点表达式 26 * */ 27 @Pointcut("execution(* com.wengde.spring.aop.ArithmeticCalculator.*(..))")// public int com.wengde.spring.aop.ArithmeticCalculator.add(int i, int j) 28 public void declareJoinPointException(){} 29 //前置通知,在ioc容器中找到与注解匹配的方法就执行 30 @Before("declareJoinPointException()") 31 public void beforeMeyhod(JoinPoint joinpoint){ 32 String methodName=joinpoint.getSignature().getName(); 33 // Object[] args=joinpoint.getArgs(); 34 // System.out.println("The method "+methodName+" begin with"+Arrays.asList(args)); 35 List<Object> args=Arrays.asList(joinpoint.getArgs()); 36 System.out.println("The method "+methodName+" begin with"+args); 37 } 38 //后置通知:在目标方法执行后执行(无论发生异常) 39 //在后置通知中不能访问目标方法执行结果 40 @After("declareJoinPointException()") 41 public void afterMethod(JoinPoint joinpoint){ 42 String methodName=joinpoint.getSignature().getName(); 43 System.out.println("The method "+methodName+" ends"); 44 } 45 //返回通知,在方法正常执行后的通知 46 @AfterReturning(value="declareJoinPointException()",returning="result") 47 public void afterReturn(JoinPoint joinpoint,Object result){ 48 String methodName=joinpoint.getSignature().getName(); 49 System.out.println("The method "+methodName+" ends"+result); 50 } 51 //异常通知,在目标方法出现异常时会执行的代码,可以访问异常对象,切可以指定指定异常时在执行通知代码 52 @AfterThrowing(value="declareJoinPointException()",throwing="e") 53 //可以访问异常对象,切可以指定指定异常时在执行通知代码 54 //public void afterThrowing(JoinPoint joinpoint,NULLPointException e){} 55 public void afterThrowing(JoinPoint joinpoint,Exception e){ 56 String methodName=joinpoint.getSignature().getName(); 57 System.out.println("The method "+methodName+" occurs"+e); 58 } 59 /* 60 * h环绕通知需要携带ProceedingJoinPoint类型的参数 61 * 环绕通知类似于动态代理的全过程,ProceedingJoinPoint类型的参数可以决定地否执行目标方法 62 * 且环绕通知必须有返回值,返回值即为目标方法的返回值 63 * 64 * */ 65 // @Around("execution(* com.wengde.spring.aop.ArithmeticCalculator.*(int , int ))") 66 // public Object aroundMethod(ProceedingJoinPoint pjd){ 67 // Object result=null; 68 // String methodName=pjd.getSignature().getName(); 69 // //执行目标方法 70 // try { 71 // //前置通知 72 // System.out.println("The method"+methodName+"begin with"+Arrays.asList(pjd.getArgs())); 73 // result= pjd.proceed(); 74 // //返回通知(方法正常执行后的通知) 75 // 76 // System.out.println("The method"+methodName+"end"+result); 77 // } catch (Throwable e) { 78 // //异常通知(方法出现异常出现的代码) 79 // System.out.println("The method"+methodName+"occurs exception"+e); 80 // throw new RuntimeException(e); 81 // } 82 // //后置通知 83 // System.out.println("The method ends "); 84 // return result;//环绕通知一定需要的这个return代码 85 // } 86 // 87 }
1 package com.wengde.spring.aop; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class Main { 7 public static void main(String[] args) { 8 ApplicationContext api=new ClassPathXmlApplicationContext("application.xml"); 9 ArithmeticCalculator arithmeticCalculator=(ArithmeticCalculator) api.getBean(ArithmeticCalculator.class); 10 System.out.println(arithmeticCalculator.getClass().getName()); 11 int result=arithmeticCalculator.add(3, 55); 12 System.out.println(result); 13 result=arithmeticCalculator.div(6, 2); 14 System.out.println(result); 15 //arithmeticCalculator.delete(4, 2);//没有返回值就是null 16 17 } 18 19 }
配置applicationContext
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 9 10 <context:component-scan base-package="com.wengde.spring.aop"></context:component-scan> 11 <!-- 使Aspectj注解起作用,使注解的java类生成代理对象,例如 before --> 12 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 13 14 </beans>
运行结果:
十月 06, 2018 11:16:00 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@df0c3a: startup date [Sat Oct 06 23:16:00 CST 2018]; root of context hierarchy 十月 06, 2018 11:16:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [application.xml] 十月 06, 2018 11:16:00 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring com.sun.proxy.$Proxy13 The method add begin with[3, 55] -----[3, 55] The method add ends The method add ends58 58 The method div begin with[6, 2] -----[6, 2] The method div ends The method div ends3 3
基于XML的方式
1 package com.wengde.spring.aop.xml; 2 import java.util.Arrays; 3 import java.util.List; 4 import org.aspectj.lang.JoinPoint; 5 import org.aspectj.lang.ProceedingJoinPoint; 6 import org.aspectj.lang.annotation.After; 7 import org.aspectj.lang.annotation.AfterReturning; 8 import org.aspectj.lang.annotation.AfterThrowing; 9 import org.aspectj.lang.annotation.Around; 10 import org.aspectj.lang.annotation.Aspect; 11 import org.aspectj.lang.annotation.Before; 12 import org.aspectj.lang.annotation.Pointcut; 13 import org.springframework.core.annotation.Order; 14 import org.springframework.stereotype.Component; 15 16 public class LoggingAspect { 17 public void beforeMethod(JoinPoint joinpoint){ 18 String methodName=joinpoint.getSignature().getName(); 19 // Object[] args=joinpoint.getArgs(); 20 // System.out.println("The method "+methodName+" begin with"+Arrays.asList(args)); 21 List<Object> args=Arrays.asList(joinpoint.getArgs()); 22 System.out.println("The method "+methodName+" begin with"+args); 23 } 24 public void afterMethod(JoinPoint joinpoint){ 25 String methodName=joinpoint.getSignature().getName(); 26 System.out.println("The method "+methodName+" ends"); 27 } 28 public void afterReturn(JoinPoint joinpoint,Object result){ 29 String methodName=joinpoint.getSignature().getName(); 30 System.out.println("The method "+methodName+" ends"+result); 31 } 32 33 public void afterThrowing(JoinPoint joinpoint,Exception e){ 34 String methodName=joinpoint.getSignature().getName(); 35 System.out.println("The method "+methodName+" occurs"+e); 36 } 37 38 // public Object aroundMethod(ProceedingJoinPoint pjd){ 39 // Object result=null; 40 // String methodName=pjd.getSignature().getName(); 41 // //执行目标方法 42 // try { 43 // //前置通知 44 // System.out.println("The method"+methodName+"begin with"+Arrays.asList(pjd.getArgs())); 45 // result= pjd.proceed(); 46 // //返回通知(方法正常执行后的通知) 47 // 48 // System.out.println("The method"+methodName+"end"+result); 49 // } catch (Throwable e) { 50 // //异常通知(方法出现异常出现的代码) 51 // System.out.println("The method"+methodName+"occurs exception"+e); 52 // throw new RuntimeException(e); 53 // } 54 // //后置通知 55 // System.out.println("The method ends "); 56 // return result;//环绕通知一定需要的这个return代码 57 // } 58 // 59 }
配置applicationContext
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 9 10 <bean id="arithmeticCalculator" class="com.wengde.spring.aop.xml.ArithmeticCalulatorImpl"></bean> 11 <!-- 配置切面的bean --> 12 <bean id="loggingAspect" class="com.wengde.spring.aop.xml.LoggingAspect"></bean> 13 <bean id="vlidation" class="com.wengde.spring.aop.xml.Vlidation"></bean> 14 <!-- 配置aop配置 --> 15 <aop:config> 16 <!-- 配置切点表达式 --> 17 <aop:pointcut expression="execution(* com.wengde.spring.aop.xml.ArithmeticCalculator.*(int , int))" id="pointcut"/> 18 <!-- 配置切面以及通知 --> 19 <aop:aspect ref="loggingAspect" order="2"> 20 <aop:before method="beforeMethod" pointcut-ref="pointcut"/> 21 <aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="result"/> 22 <aop:after method="afterMethod" pointcut-ref="pointcut"/> 23 <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> 24 </aop:aspect> 25 <aop:aspect ref="vlidation" order="1"> 26 <aop:before method="vlidation" pointcut-ref="pointcut"/> 27 </aop:aspect> 28 </aop:config> 29 </beans>
JdbcTemplate查询数据库以及事务
配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 10 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 11 <context:component-scan base-package="com.wengde.spring"></context:component-scan> 12 13 <!-- 导入资源文件 --> 14 <context:property-placeholder location="classpath:db.properties"/> 15 <!-- 配置 C3p0数据源--> 16 <bean id="dataSourse" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 17 <property name="user" value="${user}"></property> 18 <property name="password" value="${password}"></property> 19 <property name="driverClass" value="${driverClass}"></property> 20 <property name="jdbcUrl" value="${url}"></property> 21 <property name="initialPoolSize" value="${initPoolSize}"></property> 22 <property name="maxPoolSize" value="${maxPoolSize}"></property> 23 </bean> 24 <!-- 配置spring的jdbc --> 25 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 26 <property name="dataSource" ref="dataSourse"></property> 27 </bean> 28 <!-- 配置事务管理器 --> 29 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 30 <property name="dataSource" ref="dataSourse"></property> 31 32 </bean> 33 <!-- 启动事务管理器 --> 34 <tx:annotation-driven transaction-manager="transactionManager"/> 35 </beans>
test类
1 package com.wengde.spring.jdbc; 2 3 import static org.junit.Assert.*; 4 5 import java.sql.SQLException; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 import javax.sql.DataSource; 10 11 import org.junit.Test; 12 import org.springframework.context.ApplicationContext; 13 import org.springframework.context.support.ClassPathXmlApplicationContext; 14 import org.springframework.jdbc.core.BeanPropertyRowMapper; 15 import org.springframework.jdbc.core.JdbcTemplate; 16 import org.springframework.jdbc.core.RowMapper; 17 18 19 public class JDBCtest { 20 private ApplicationContext api=null; 21 private JdbcTemplate jdbcTemplate; 22 { 23 api=new ClassPathXmlApplicationContext("applicationContext.xml"); 24 jdbcTemplate=(JdbcTemplate) api.getBean("jdbcTemplate"); 25 26 } 27 @Test 28 public void testDataSourse() throws SQLException { 29 DataSource dataSource=(DataSource) api.getBean("dataSourse"); 30 System.out.println(dataSource.getConnection()); 31 } 32 /*执行insert,update,delete 33 * 34 * 35 */ 36 @Test 37 public void testUpdate(){ 38 String sql="update mybooks set Title=? where id=?"; 39 jdbcTemplate.update(sql, "java",1); 40 } 41 /*执行批量更新,批量insert,批量update,批量delete 42 * 43 * */ 44 @Test 45 public void testBathUpdate(){ 46 String sql="insert into mybooks(author,title,price,Publishingdate,Salesamount,Storenumber,Remark) values(?,?,?,?,?,?,?)"; 47 List<Object[]> batchArgs=new ArrayList<Object[]>(); 48 batchArgs.add(new Object[]{"zhang","AA","120","2018-10-5","55","66","加油"}); 49 batchArgs.add(new Object[]{"li","BB","130","2018-10-4","77","88","努力"}); 50 jdbcTemplate.batchUpdate(sql, batchArgs); 51 52 } 53 /* 获取一个对象 54 * 注意不是调用queryForObject(String sql, Class<Book> requiredType, Object... args) 方法,该方法是获取某一个字段的值 55 * 而需要调用queryForObject(String sql, RowMapper<Book> rowMapper, Object... args) 56 * 1.其中的rowMapper指定如何去映射结果集的行,常用的实现类是BeanPropertyRowMapper 57 * 58 * */ 59 @Test 60 public void testQueryObject(){ 61 String sql ="select * from mybooks where id=?"; 62 // Book book= jdbcTemplate.queryForObject(sql, Book.class, 1); 63 RowMapper<Book> rowMapper=new BeanPropertyRowMapper<Book>(Book.class); 64 Book book=jdbcTemplate.queryForObject(sql, rowMapper, 1); 65 System.out.println(book); 66 67 } 68 /*查询实体类的集合 69 * 注意 调用的不是queryForlist()方法 70 * 71 * 72 * */ 73 @Test 74 public void testQueryForlist(){ 75 String sql ="select * from mybooks where id<?"; 76 RowMapper<Book> rowMapper=new BeanPropertyRowMapper<Book>(Book.class); 77 List<Book> books=jdbcTemplate.query(sql, rowMapper,5); 78 System.out.println(books); 79 80 } 81 /* 82 * 查询单列的值或者统计查询 83 * queryForObject(String sql, Class<Long> requiredType) 84 * */ 85 @Test 86 public void testQueryForObject(){ 87 String sql="select count(id) from mybooks"; 88 long count=jdbcTemplate.queryForObject(sql, Long.class); 89 System.out.println(count); 90 } 91 }
基于xml文件的事务配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 10 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 11 12 13 <!-- 导入资源文件 --> 14 <context:property-placeholder location="classpath:db.properties"/> 15 <!-- 配置 C3p0数据源--> 16 <bean id="dataSourse" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 17 <property name="user" value="${user}"></property> 18 <property name="password" value="${password}"></property> 19 <property name="driverClass" value="${driverClass}"></property> 20 <property name="jdbcUrl" value="${url}"></property> 21 <property name="initialPoolSize" value="${initPoolSize}"></property> 22 <property name="maxPoolSize" value="${maxPoolSize}"></property> 23 </bean> 24 <!-- 配置Spring的Jdbctemplate --> 25 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 26 <property name="dataSource" ref="dataSourse"></property> 27 </bean> 28 <!-- 配置bean --> 29 <bean id="bookStockDao" class="com.wengde.spring.tx.xml.BookStockDaoImpl"> 30 <property name="jdbcTemplate" ref="jdbcTemplate"></property> 31 </bean> 32 <bean id="bookShopServic" class="com.wengde.spring.tx.xml.service.impl.BookShopServiceImpl"> 33 <property name="bookShopDao" ref="bookStockDao"></property> 34 </bean> 35 <bean id="cashier" class="com.wengde.spring.tx.xml.service.impl.CashierImpl"> 36 <property name="bookShopService" ref="bookShopServic"></property> 37 </bean> 38 39 <!-- 配置事务管理器 --> 40 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 41 <property name="dataSource" ref="dataSourse"></property> 42 </bean> 43 <!-- 配置事务属性 --> 44 <tx:advice id="txadvice" transaction-manager="transactionManager"> 45 <tx:attributes> 46 <!-- 根据方法名指定事务的属性 --> 47 <tx:method name="purchase" propagation="REQUIRES_NEW"/> 48 <tx:method name="*"/> 49 </tx:attributes> 50 </tx:advice> 51 <!-- 配置事务切入点,以及把事务切入点和事务属性关联起来 --> 52 <aop:config> 53 <aop:pointcut expression="execution(* com.wengde.spring.tx.xml.service.*.*(..) )" id="txPointCut"/> 54 <aop:advisor advice-ref="txadvice" pointcut-ref="txPointCut"/> 55 </aop:config> 56 </beans>