spring学习

学习流程

  1. spring framework (IOC( 控制反转)/ DI(依赖注入) ,jdbc ,aop/sif4j(简单日志记录外观))(单体应用/微服务)
  2. spring mvc /struts2
  3. mybatis(国内主流)/hibernate(ORM)(国外主流)
  4. spring boot(补充)

扩展知识

shiro权限管理

restful风格

中间件(rabbitmq,kafka)跟spring AMQP整合

Tomcat集群session共享

Redis内存数据库

内存数据库(tt)

搭建maven库

引入配置文件

      	//配置文件后缀.properties
      	office.properties//配置文件
            
      	ResourceBundle bundle=ResourceBundle.getBundle("配置文件名字");//不能加扩展名
        String key=bundle.getObject("office")+"";//查找配置文件里面的key值

IOC容器

pom.xml文件 maven项目必备配置文件

https://mvnrepository.com/ maven存储库

  <dependencies>
	<!-- https://mvnrepository.com/artifact/junit/junit -->
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.13</version>
		<scope>test</scope>
	</dependency>

	<!-- https://mvnrepository.com/artifact/org.springframework/spring -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring</artifactId>
		<version>5.2.2.RELEASE</version>
		<type>pom</type>
	</dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.5.0</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.48</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.2.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
         </dependency>
  </dependencies>
<!--实例化PPT类的对象-->
<bean id="office" class="com.stone.service.impl.PPT" scope="singleton"></bean>

Class.forName(xxx.xx.xx) 返回的是一个类

  • jvm会查找指定路径类的class文件,然后将class文件读入内存,为该类生成一个class对象作为访问类型信息的入口(类型信息是该类的class文件转换成的数据结构,存储在方法区,class对象就是用于访问这个数据结构的,我们可以通过getClass()方法获取class对象,class对象提供的反射功能其实就是基于该数据结构实现的)
  • 会为类的类变量分配空间并赋值、执行静态代码块中的内容,也就是对类进行初始化比如我们熟悉的Class.forName(“com.mysql.jdbc.Driver”),就是告诉jvm加载并初始化Driver类,大家可以进到Driver类中查看其源码,核心内容除了其父类的一些静态变量外,就是Driver类本身的静态代码块了,其中执行了DriverManager.registerDriver(new Driver()),这样一句代码,顾名思义,会创建一个驱动对象,然后进行注册

static{

//静态块,只加载一次

}

bean标签:指定要创建的实体类

ID属性:可以为任意值,但是在整个配置文件中唯一

class属性:要实例化类的权限定名

scope属性:范围属性。

什么时候用默认值singleton?什么时候用prototype?

action:用prototype

service/dao:singleton

init-method属性:定义初始化方法

destory-method属性:指定销毁方法

xml文件放在resources文件夹下

DI依赖注入:

普通注入:

set方法同等于property属性,

name属性名

value赋的值

构造器注入:constructcr-arg

postgress数据库 gitlab数据库 gathub数据库 高斯数据库 mycat分布分表

druid连接池

 <!-- 使用配置文件 -->
 <context:property-placeholder location="classpath:config/db/mysql.properties"/>
	//jdbc基本类型  --与数据库类型做匹配
		jdbctemplate.update(sql,params,new int[] {Types.CHAR,Types.CHAR,Types.CHAR,Types.DATE});
		

柔性事务

事务

IOC(控制反转)

搭建IOC环境:beans ,core,context,expression,log4j

bean标签

加载配置文件applicationContext.xml

ApplicationContext context=new ClassPathXmlApplicationContext("applicationBontext.xml");
User user=context.getbean("abc");//实例化

applicationContext.xml

<bean id="" class="" scope="singleton/prototype"></bean>

socpe属性 singleton: 单实例 默认值 配置文件只要一加载 就会创建该实例对象 放在spring容器中 (Map

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JVUhEZiv-1626491360599)(C:\Users\徐志磊\AppData\Roaming\Typora\typora-user-images\image-20200313092426684.png)]

prototype: 多实例**
配置文件只要一加载 不创建该实例对象
当所有人过来要的时候(getBean(“user”)) 才创建该实例对象 放在spring容器中
注意:获取一次 创建一次 放在spring容器中**

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tvWj8nY8-1626491360606)(C:\Users\徐志磊\AppData\Roaming\Typora\typora-user-images\image-20200313092709479.png)]

使用场景:

action:prototype

service/dao:singleton

singleton的对象当spring容器关闭的时候销毁

prototype的对象长时间不用就会自动销毁

init-method属性

init-method:指定初始化方法

destory-method属性

destory-method:指定销毁方法

 <bean id="user" class="com.stone.spring01.User" scope="singleton" init-method="aaa" destroy-method="bbb"></bean>

import标签

<import resource=""  // <!--  <import resource="applicationBontext2.xml"/>-->

DI:属性的依赖注入

在IOC创建的时候有属性就会DI赋值进去。

DI是在IOC的基础上进行对象的属性注入的

set属性注入:要有set/get方法

property标签:

name:要复制的属性名

value:要赋的值

ref:针对对象类型。 指向spring中bean的id名

这个对象必须要创建好

构造器方式

导入外部文件.properties

导入这个文件需要添加标题头如下:

<?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"> <!-- bean definitions here -->

</beans>

context标签

 <context:property-placeholder location="classpath:jdbc.properties"/>

数据库整合

applicationContext.xml里面创建IOC容器对象

<!--c3p0-->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"></property>
    <property name="jdbcUrl" value="${jdbc.url}"></property>
    <property name="user" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>
    
    <!-- DBCP -->
    <bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driver}"></property>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

jdbc.property配置文件

//mysql
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/1905db
jdbc.username=root
jdbc.password=

//orcl
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:oracle://localhost:3306/hibernate
#jdbc.username=root
#jdbc.password=

//db2
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:db2://localhost:3306/hibernate
#jdbc.username=root
#jdbc.password=

测试文件

test.java

	//c3p0方式
	@Test
	public void test(){
	
		ApplicationContext context=new ClassPathXmlApplicationContext("applicationBontext.xml");
		DataSource ds=(DataSource)context.getBean("c3p0");
		
		try {
			Connection con=ds.getConnection();
			System.out.println(con);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

spring的IOC注解

第一步,导包,aop

第二部:开启注解扫描器

<context:component-scan base-package="con.stone"></context:component-scan>

@Component(“bean的id值”) 定义在类上 只要定义在了类上
那么注解扫描器只要一扫描到就会创建该类的实例对象 放在spring容器中
spring发布了公告, @Component这个注解不维护了,要维护这个注解下面衍生出的3个注解
@Controller(“bean的id值”) 针对的就是web层
@Service(“bean的id值”) 针对的是service层
@Repository(“bean的id值”) 针对的是dao层

			@Value("属性值") 定义在属性字段上 针对的是基本类型和String类型
				         如果使用了这个注解 该属性的set方法可以省略不写
			@Autowired     定义在属性字段上的 针对的是对象类型
					如果定义在了那个对象类型的属性身上 会自动去spring容器中找该类型的实例对象给赋值
				
			@Qualifier("userDaoxxx")定义在属性字段上的 指定用该类型的哪个id名称的实例对象
			注意: @Qualifier要想使用 必须结合 @Autowired 一起使用
				@Resource(name="userDaoxxx")
					@Autowired+@Qualifier("userDaoxxx")

	 了解的注解:
			@Scope("singleton"或则prototype)  定义在类上的 指定当前类是单实例还是多实例

			@PostConstruct  定义在方法上  配置初始化方法
			@PreDestroy     定义在方法上 配置销毁的方法

spring整合Junit

//首先加载xml文件
@ContextConfiguration(value = "classpath:applicationBontext.xml")
//然后加载配置文件
@RunWith(value = SpringJUnit4ClassRunner.class)
public class SpringJunit {

	@Autowired
	private UserService userService;
	
	@Autowired
	private UserDao userDao;
	
	@Test
	public void test() {
		userService.save();
	}
}

AOP面向切面编程

AOP基本概念:

1、连接点(joinpoint):类种的所有方法

2、切入点(pointcut):有共性功能代码的方法

3、通知(Advice):被抽取的共性功能的代码逻辑,通知有位置之分,叫通知类型。前置通知,后置通知

4、引入(Introduction):通知只能抽取逻辑代码,变量是拿不出来的,把变量引入到切点方法中去,就要用引入

5、目标对象(target Object):有切入点的方法的对象

6、AOP代理(AOP Proxy):代理目标对象就叫做AOP代理

7、织入(weaving):代理对象把通知织入到目标对象的切入点方法中,是一个动作

8、切面(Aspect):通知和切入点之间的关系

通知的五种方法

before前置通知,在方法执行之前执行

after后置通知,在方法执行之后执行

afterreturning返回通知,在方法返回结果之后执行

afterthrowing后置异常通知,在方法抛出异常后执行

around环绕通知(proceedingjoinpoint pjp)围绕方法执行,有返回值

pjp.proceed

注解:

@aspect 注解在类上,标注切面类

@before(value=“execution(目标方法)”)注解在方法上,

AOP原理

动态代理:jdk的动态代理

​ 使用jdk额java.lang.reflect.proxy

//创建目标对象
userDao userdao=new userDaoimpl();
//jdk的动态代理,来实现代理上面的userdao对象,并对功能增强

InvocationHandler h=new myInvocationHandle(userdao);
//newProxyInstance三个参数的意思
//1、loader:类加载器,累的字节码对象获得
//2、interfaces得到该对象所有实现接口的字节码对象的数组
//3、需要实现InvocationHandler端口的对象,这步骤需要自己动手实现,对目标对象方法功能的增强就是这个方法中完成的

//返回的是代理对象
Object newProxyInstance =Proxy.newProxyInstance(userdao.getClass().getClassLoader(),userdao.getLcass().getInterfaces(),h);
userDao proxy=(userDao)newProxyInstance;
proxy.add();
private class myInvocationHandle inplements InvocationHandle{
    Object obj;
    
    public myInvocationHandle(Object obj){
        this.obj=obj;
    }
    
    //
    
    @Override
    public Object invoke(Object proxy,Method mothod,Object[]args)thorws Thorwable{
        
        Object obj1=mothod.invoke(obj,args)
    }
}
			cglib代理

配置bean

applicationContext代表IOC容器

ClassPathXmlApplicationContext加载配置文件

FileSystemXmlApplicationContext从文件系统加载配置文件

class:bean的全类名,通过反射的方式在IOC容器中创建bean,要求bean必须有无参数的构造器

id标识容器中的bean。id唯一

scope范围

singleton单实例 ,只要配置文件加载就会创建对象,所有使用都是同一个对象

prototype多实例,配置文件创建,但不会创建对象,只有getbean的时候才会去调用,所有访问都是不同的对象

action:prototype

service/dao:singleton

init-method:指定初始化方法

destory-method:指定销毁方法

import导入外部的配置文件resource外部配置文件的地址

<import resource="xxx.xml">

DI依赖注入

​ property:是set属性的方式

​ name:要赋值的属性名

​ value:要赋的值,针对基本类型

​ ref:要赋的对象属性,针对对象类型,指向bean的id名

   <!-- set注入 -->
   <!-- 属性必须要有set方法 -->
  	<bean id="user" class="spring.com.stone.beans.User" scope="">
  		<property name="name" value="mary" ></property>
  		<property name="age" value="12"></property>
  	</bean>
    <!-- 构造器注入 可以指定参数的位置-->
    <!-- 必须要有参构造方法-->
	<bean id="car" class="spring.com.stone.beans.Car">
		<constructor-arg name="brand" value="audi"></constructor-arg>
		<constructor-arg name="corp" value="shanghai"></constructor-arg>
		<constructor-arg name="price" value="120000"></constructor-arg>
	</bean>

复杂属性注入(map,list,[]..属性注入)

<bean id="collBean" class="spring.com.stone.beans.CollBean">
	   	 	 <property name="ss">
	   	 	 		<!-- 数组类型 -->
	   	 	 		<list>
	   	 	 			<value>aaa</value>
	   	 	 			<value>bbb</value>
	   	 	 			<value>ccc</value>
	   	 	 		</list>
	   	 	 </property>
	   	 	 
	   	 	 <property name="ll">
	   	 	 		<!-- list类型  -->
	   	 	 		<list>
	   	 	 			<value>111</value>
	   	 	 			<value>222</value>
	   	 	 			<ref bean="car"/>
	   	 	 		</list>
	   	 	 </property>
	   	 	 
	   	 	 <property name="mm">
	   	 	 	<!-- map -->
	   	 	 	<map>
	   	 	 		<entry key="k1" value="aaa"></entry>
	   	 	 		<entry key="k2" value="bbbb"></entry>
	   	 	 		<entry key="k3" value-ref="car"></entry>
	   	 	 	</map>
	   	 	 </property>
	   	 	 
	   	 	 <property name="properties">
	   	 	 	<!-- properties类型 -->
	   	 	 	<props>
	   	 	 		<prop key="hibernate.username">root</prop>
	   	 	 		<prop key="hibernate.password">1234</prop>
	   	 	 	</props>
	   	 	 </property>
	   	 </bean>

整合连接池(c3p0,jdbc...)

	@Test //硬编码c3p0
	public void test() throws  Exception {
		// c3p0
		ComboPooledDataSource dateSource=new ComboPooledDataSource();
		//设置驱动
		dateSource.setDriverClass("com.mysql.jdbc.Dricer");
		//设置地址
		dateSource.setJdbcUrl("jdbc:mysql://localhost:3306/1905db");
		//设置用户名
		dateSource.setUser("root");
		//设置密码
		dateSource.setPassword("");
		
		//问连接池要连接对象
		Connection con = dateSource.getConnection();
		System.out.println(con);
	}

	@Test //DBCP的硬编码方式
	public void test2() throws SQLException
	{
		BasicDataSource dataSource = new BasicDataSource(); // ioc
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/1905db");
		dataSource.setUsername("root");
		dataSource.setPassword("");    //di
		Connection con = dataSource.getConnection();
		System.out.println(con);
	}
	<!-- 引入配置文件 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	<!-- c3p0 -->
	<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- dbcp -->
 	<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driver}"></property>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean> 

IOC控制反转

开始注解扫描器:告诉spring应该去哪个包去解析注解

配置注解组件

​ 半注解:

​ 自己的类用注解,别人的类用xml

常用注解组件:

@Component(“bean的id值”)注解在类上,和创建bean一样

​ @Controller(“bean的id值”) 针对的是web层

​ @Service(“bean的id值”)针对的是server层

​ @Repository(“bean的id值”)针对的是dao层

@value(“xxx”)注解在属性上,给属性赋值

@Autowired注解在对象属性上,自动赋值

​ @Qualifier("")指定用该类型的那个名称的实例对象,@Qualifier使用必须结合@Autowired

@Resource(name="")可以代替@Autowired和@Qualifier("")

需要了解的注解

@Scope(“singleton"或者"prototype”) 定义在类上,指定当前类是单实例还是多实例

@PostConstruct 定义在方法上 配置初始化方法

@PreDestroy 定义在方法上 配置销毁的方法

//开启注解扫描器 
<context:component-scan base-package="spring.com.stone"></context:component-scan>

​ 全注解

需要有一个注解类,不在加载配置文件 而是加载这个注解类

//注解类
@Configuration//注解该类是个配置类
@ComponentScan(basePackages="spring.com.stone")//注解去哪里扫描包
@PropertySource(value = "classpath:jdbc.properties")//注解去哪里加载文件
//注解在注解类上
//别人的类
	@Bean(name="c3p0")
	//创建c3p0连接池给spring容器
	public DataSource createDataSourcec3p0() throws Exception {
		
		ComboPooledDataSource dateSource=new ComboPooledDataSource();
		//设置驱动
		dateSource.setDriverClass("com.mysql.jdbc.Dricer");
		//设置地址
		dateSource.setJdbcUrl("jdbc:mysql://localhost:3306/1905db");
		//设置用户名
		dateSource.setUser("root");
		//设置密码
		dateSource.setPassword("");
		return dateSource;	
	}


//加载注解类
ApplicationContext context= new AnnotationConfigApplicationContext(springconfig.class);

spring整合Junit

//告诉spring配置文件在哪个地方
@ContextConfiguration(value = "classpath:applicationContext.xml")
//告诉spring谁加载配置文件
@RunWith(value = SpringJUnit4ClassRunner.class)
//注解在测试类上

spring-AOP
<!-- 配置aop -->
	<aop:config>
	<!-- 配置切面
	配置通知与切面之间的关系
	要把通知,切入点所在的类配置成spring管理的bean -->
		<aop:aspect ref="MyAdice">
            <!-- 插入方法before、atfer、after-returning 、after-throwing、around-->
            <--method:通知方法名
                pointcut:目标方法中的方法
                pointcut(切入点表达式) 可以使用通配符使用"*.." 标识任意多个包
                    参数也可以使用通配符*
                    .. 代表任意个参数-->
			<aop:before method="before" pointcut="execution(public void com.stone.beans.TargetObject.method(int, int))"/>
		</aop:aspect>
	</aop:config>
	
	<!-- 配置目标对象 -->
	<bean id="TargetObject" class="com.stone.beans.TargetObject"></bean>
	<!-- 配置通知对象 -->
	<bean id="MyAdice" class="com.stone.beans.MyAdice"></bean>

织入

编译期织入

装载时织入

运行时织入 spring属于运行时织入

切入点配置方式

局部切入点:普通就是局部

<aop:aspect ref="MyAdice">
			
			<aop:after method="after" pointcut="execution(public void com.stone.beans.TargetObject.method(int, int))"/>

		</aop:aspect>

切面间共享切入点

//定义且面积按共享方法
<aop:pointcut expression="execution(* *..method(..))" id="method"/>
    
    <aop:aspect ref="MyAdice">
			<aop:before method="before" pointcut-ref="method"/>
	</aop:aspect>

切面内共享切入点

    <aop:aspect ref="MyAdice">
        <aop:pointcut expression="execution(* *..method(..))" id="method"/>
		<aop:before method="before" pointcut-ref="method"/>
         <aop:before method="after" pointcut-ref="method"/>
	</aop:aspect>
//通知类
public class MyAdice {

    //应用于各种校验
	public void before() {
		System.out.println("before......");
	}
	//应用于清理现场
	public void after() {
		System.out.println("after.......");
	}
	//应用于常规数据处理
	public void afterReturning() {
		System.out.println("afterReturning...");
	}
	//应用于包装异常
	public void afterthrowing() {
		System.out.println("afterthrowing...");
	}
	/*
	*可以做任何事
	*在环绕通知时,需要传递一个ProceedingJoinPoint类对象,然后调用proceed()方法
	*才会完整执行,否则只会做前置输出,结果和后置通知不会出来
	*/
	public void around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("around...start");
		pjp.proceed();
		System.out.println("around...end");
	}
}

获取匹配方法参数

//通过在方法里传递JoinPoint jp形参
//例 
public void before(JoinPoint jp) {
		Object[] args=jp.getArgs();
		for(int i=0;i<args.length;i++) {
			System.out.println(args[i]);
		}
		System.out.println("before......");
		
	}

获取对象参数

获取返回值

获取通知的返回值。returning=""

throwing=“”

注解aop

/*开启扫描
*创建目标对象和通知bean
*给通知配置切面
*开启aop空间
给通知方法添加注解*/

//通知类
@Component("myAdice")
@Aspect
public class MyAdice {

	@Before(value = "execution(* *..method(..))")
	public void before(JoinPoint jp) {
		Object[] args=jp.getArgs();
		for(int i=0;i<args.length;i++) {
			System.out.println(args[i]);
		}
		System.out.println("before......");
		
	}
	@After(value = "execution(* *..method(..))")
	public void after() {
		System.out.println("after.......");
	}
	
	public void afterReturning() {
		System.out.println("afterReturning...");
	}
	
	public void afterthrowing() {
		System.out.println("afterthrowing...");
	}
	
	public void around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("around...start");
		pjp.proceed();
		System.out.println("around...end");
	}
}

//目标对象
@Component("targetObject")
public class TargetObject {

	public void method(int i,int j) {
		int sub=i+j;
		System.out.println(sub);
	}
}
//配置文件
	<context:component-scan base-package="com.stone"></context:component-scan>
 //把aop注解功能打开
		<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
 //测试方法    
	@Test
	public void test() {
		// TODO Auto-generated method stub
		ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext-aop.xml");
		TargetObject targetObject=(TargetObject) context.getBean("targetObject");
		targetObject.method(22,11);
	}

通知方法顺序

哪个在前就会先执行哪一个

jdk的动态代理

前提:对象必须要有实现接口,可以指定这个接口下的哪一个方法

使用jdk的java.lang.reflect.Proxy类的newPRoxyInstance方法实现动态代理

//jdk动态代理
//测试类
@Test
	public void test() {
		//创建目标对象
		com.stone.aop.jdk.proxy.userDao user=new userDaoImpl();
		
		
		//jdk的动态代理
		/*
		 *newProxyInstance方法的是哪个参数是什么意思 
		 *1、loader:类加载器(类的字节码获得)写法固定
		 *2、interfaces得到该对象实现接口的字节码对象的数组,写法固定
		 *3、需要一个实现了InvacationHandler接口的对象,这步需要自己动手实现
		 *	 对目标对象方法功能的增强就是这个对象完成的
		 */
		InvocationHandler h =new myInvocationHandler(user);
		Object newProxyInstance=Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), h);
		userDao proxy=(userDao) newProxyInstance;
		proxy.add();
		proxy.delete();
	}



	//实现了InvacationHandler接口的对象
	//该类对目标对象进行代理并进行功能增强的具体实现类
public class myInvocationHandler implements InvocationHandler{

	//定义目标对象
	Object obj;
	
	public myInvocationHandler(Object obj) {
		// TODO Auto-generated constructor stub
		this.obj=obj;
	}
	
	/*
	 * proxy:被代理的对象(不用)
	 * method:目标对象的方法对象,jdk传递过来
	 * args,是该方法对象的参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("初始化...");//前置通知...
		
		Object obj2=method.invoke(obj, args);
		
		System.out.println("结束...");//后置通知...
		return obj2;
	}

}

//对方法判断添加增强
Object obj2=null;
		if(method.getName().equals("add")) {
			System.out.println("初始化...");//前置通知...
			
			 obj2=method.invoke(obj, args);
			
			System.out.println("结束...");//后置通知...
		}else {
			 obj2=method.invoke(obj, args);
		}

cglib动态代理java

/*
 *不需要接口,也可以指定增强方法
 * cglib动态代理的实现步骤
 * 		1、生成字节码对象(空的)Enhancer
 * 		2、设定这个字节码对象的父类students(目标对象的类)
 * 		3、设置增强方法,毁掉方法,拦截的方法
 * 		4、得到代理对象
 */
@Test
public void test() {
	Enhancer en =new Enhancer();//生成字节码对象(空的)Enhancer
	en.setSuperclass(Students.class);//设定这个字节码对象的父类students(目标对象的类)
	
	Callback callback = new CallbackMethod();//设置增强方法,毁掉方法,拦截的方法
	en.setCallback(callback);//得到代理对象
	
	Students stu=(Students) en.create();
	
	stu.name();
}

public class CallbackMethod implements MethodInterceptor{

/*
 * proxy:代理对象
 * method:目标对象中方法
 * args:目标对象方法的参数
 * methodProxy:代理对象中代理对象方法
 */
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
	
	System.out.println("前置方法....");
	
	Object object= methodProxy.invokeSuper(proxy, args);
	
	System.out.println("后置方法....");
	
	return object;
}
}

spring的jdbcTempalte

jdbcTempalte是spring提供的到曾用来和数据库数据交互的技术

jdbcTempalte是spring对jdbc+c3p0的封装

hibernateTemplate 是spring对hibernate又封装一次

mybatis 对jdbc+c3p0的封装

spring的声明式事务

事务特性ACID

原子性:一件完成的事,要不全部成功,要不全部失败

一致性:事务对的前后,数据总数不发生变化

隔离性:只要事务已完成,数据就会到数据库中

持久性:事务具备隔离性,如果没有隔离性,就会发送读取数据的问题

​ 布局别隔离性的话,会发生问题:

​ 脏读

​ 重复读

​ 虚度/幻读:一个事务中,读取了另一个事务还没有提交的数据

spring的事务控制都是基于

配置文件的方式,-------xml方式

	<!-- 切面类 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
			<property name="dataSource" ref="c3p0"></property>
	</bean>
	<!-- 配置DataSourceTransactionManager里面事务方法的一些参数
		 不写 该方法使用的事务参数都是默认值
	 -->
	<tx:advice transaction-manager="transactionManager" id="txadvice">
			<tx:attributes>
				<tx:method name="tranfer"/>
			</tx:attributes>
	</tx:advice>
	
	<!-- 织入 -->
	<aop:config>
		<aop:pointcut expression="execution(* cn.itcast.serviceimpl.TranFerServiceImpl.tranfer(..))" id="pointcut"/>
		<!-- 针对事务的配置标签 -->
		<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/>
	</aop:config>

事务的注解
  <!-- 切面类 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
			<property name="dataSource" ref="c3p0"></property>
	</bean>

<!-- 自己的类 -->
	
	<!-- 开启注解扫描器 -->
	<context:component-scan base-package="cn.itcast"></context:component-scan>

	<!-- 开启事务的注解配置 告诉使用的是哪个类下的事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
        
        
   //方法使用注解
        @Transactional
 // 注解在类上,就是每个方法都配置事务,注解在方法上,就是这个方法开启事务

spring整合hibernate

整合什么?

1)有IOC容器来管理hibernate的seesionFactory

2)让hibernate使用spring的声明式事务

步骤:

先加入hibernate

配置hibernate.cfg.xml

配置hibernate的基本属性

  1. 数据源需配置到IOC容器中,所以此处不再需要配置数据源

  2. 关联的hbm.xml也在IOC容器配置sessionfactoey实例再进行配置

  3. 配置hibernate的基本属性:方言,SQL 显示及格式化,生成数据表的策略以及二级缓存等

再加入spring

整合

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值