spring个人学习笔记

(自己学习过程笔记,可能有错误,仅备忘)
一、Spring框架的术语:

1.组件/框架设计:
侵入式:对现有的类的结构有影响
非侵入式:对现有的类的结构没有影响

2.控制反转(IOC):
对象的创建交给外部容器(IOC容器)。

3.依赖注入(DI):
处理对象的依赖关系

区别:控制反转:解决对象的创建问题
依赖注入:在创建完成之后,对象的关系方的处理(set方法注入)

4.AOP:面向切面编程

二、Spring框架的概述
解决对象创建以及对象之间的依赖关系的一种框架,可与其他框架一起使用。
作用:整合

三、Spring提供了一站式解决方案:
(六大模块)
1.Spring Core:Spring核心功能,IOC容器
2.Spring web:对WEB模块的支持
3.Spring DAO:对于JDBC支持
4.SpringORM:对ORM的支持
5.SPring AOP:切面编程
6.Spring EE:对Java EE其他模块的支持

![spring模块图](https://img-blog.csdnimg.cn/20200323084551642.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzY5MzMzNQ==,size_16,color_FFFFFF,t_70#pic_center)

四、IOC编写(xml开发方式)

1.搭建IOC环境
导包:core、beans、context、expression
日志依赖包:(属于apache)
commons-logging.jar(必导),apache-log4j.jar(可选)

2.创建一个类(因为IOC就是针对类的)
3.在src下创建applicationContext.xml(相当于IOC容器)
4.通过IOC容器创建类的实例对象


```java
  ApplicationContext context  = new ClassPathXmlApplicationContext("applicationContext.xml");//获取容器/获取工厂
		
  Classname clsname = (Classname)context.getBean("idname");//通过id获取相应对象

 注:
 1.bean标签指定要实例化的对象<bean id = "abc"  class="LIN.zd.User" scope="prototype"></bean>
   <bean>还有一个属性 scope="singleton/prototype",默认为singleton。
    1)  singleton(单实例): 当获取容器(配置文件一加载 new ClassPathXmlApplicationContext("applicationContext.xml"))
         时创建对象放入IOC容器中,此后通过getBean()方法获取的都是同一个对象。
          应用于:service/dao
     2)  prototype(多实例):每通过getBean()方法获取对象时,就创建一个实例。
           应用于action
     3)还有属性init-method和destroy-method="方法名"指定相应的方法为初始化方法和销毁方法。
          IOC容器的关闭(ClassPathXmlApplicationContext  context.close())。
2.<import resourse="xxx.xml">
       可以将其他xml文件导入
3.工厂模式就是把对象的new交给工厂类。
   工厂类读取配置文件,进行解析然后创建(如读取类名的字符串来进行创建,也就是说xml文件是一个具有特殊格式的文件供读取)。
而spring框架已经帮我们实现了工厂,不需要我们写。通过工厂+配置文件+反射的形式(工厂读取配置文件,采用反射的形式创建对象)
4.工程类有旧和新


```java
旧:BeanFactory
Resource resource = new FileSystemResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);

ClassPathResource resource = new ClassPathResource("beans.xml");
BeanFactory factory = new XmlBeanFactory(resource);
新:ApplicationContext--->实现了BeanFactory接口
   他有两个实现类:
       ClassPathXmlApplicationContext:类路径(src)下读取文件
      FileSystemXmlApplicationContext:文件系统下加载(如磁盘)

还有一个注解形式的AnnotatiaonApplicationContext(“扫描的包(类中有注解)”);

五、依赖注入(DI)
1.DI是在IOC的基础上进行对象属性的赋值。
2.DI的属性注入方式:
1)构造器注入方式:类中要有有参构造器(必须显示声明无参构造器)

    <bean id = "abc"  class="LIN.zd.User" scope="prototype">
       <constructor-arg name="属性名" value="属性值" / ref="属性值">   </constructor-arg>
    </bean>

     注:value针对的是基本类型和String类型,ref针对的是对象(填的是spring中有的对象的id)。

2)set方法注入:必须有set方法(重点)


3)p名称空间注入

4)复杂属性(map,list[],…)注入(这里使用set的方式)

对于数组、list用标签

<bean id = "abc"  class="LIN.zd.User" scope="prototype">
           <property name="属性名" >
               <list>
                     <value>111</value>
                     <value></value>
                      <ref></ref>
                      <ref></ref>
                </list>
            </property>
 </bean>

对于set用标签
对于map用标签

<property name="arr">
   <array>122<array>
</propetty>
<bean id = "abc"  class="LIN.zd.User" scope="prototype">
           <property name="属性名" >
               <map>
                   <entry key=""  value=""></entry>
                    <entry key=""  value-ref=""></entry>
                </map>
            </property>
</bean>

对于.properties文件

<bean id = "abc"  class="LIN.zd.User" scope="prototype">
           <property name="属性名" >
               <props>
                   <prop key="">value</prop>
                    <prop key="">value</prop>
                </props>
            </property>
 </bean> 
 

五、IOC的注解方式
1.首先导包,除了导xml方式的所有包之外,还应该导入AOP包;
2.编写类
2.配置xml文件,约束头是Context的(xml是Bean)。
引入组件扫描的标签配置<context:component-scan base-package=“类的包名”/>
4.在类上添加注解@component(value=“等于写入id”)
注:三个衍生类,便于分层开发,目前一样
@Conntroller
@Service
@Repository

5.属性注入:
1)普通属性@Value("")
若无set方法,则在属性上@Value("")
若有set方法,则在set上@Value("")
2) 对象属性@Autowired//但是按类型完成注入,不是按id
@Autowired与@Qualifier(“id名”)联用即按id
@Resourse(name="")按id

注:1.xml优先的原则:注解如@Autowird来输入时,其实是优先在xml配置文档找bing(即使开了组件扫描,不必配合其他注解使用,比如使用
@Autowird,注入Da对象,可以在文档中配置相应的bean,也可一在dao类上注解@Repository。也正是因为这样,在使用
@Autowired注入时,如果在xml配置有相对应的bean,这时若果其配置了property而类中却没有setter方法,就会报错)
2.@Autowird因为是按类型来输入的,但是如果这时候有一个父接口有多个实现类,那么这时候可以与@Qualifier(“id名”)
联用来选择哪一个实现类。
3.@Resource(name = “userDao”)与@Repository(value=“userdao”),
@Resourse(name="")按id(xml中)

	3)bean的其他注解:
	  @PostConstruct初始化方法:修饰实例方法,在构造方法之后,init()之前
	  @preDestroy销毁方法,destroy()之后
	  @Scope作用域:@scope("prototype")

==============================================================================================================
AOP:切面编程
一、AOP的底层实现是动态代理
JDK代理
cglib代理
注:目前个人理解是,将对象交给一个代理,该代理类似对象的增强版,对方法的增强(如添加一些权限校验等)

二、AOP的相关术语

   Joinpoint:连接点,类中可以进行增强的方法就是连接点(比如数据库的dao中增删改查都是切入点)
   Pointcut:切入点,真正进行增强的点(连接点并不一定全部进行增强)
   Advice:通知,增强(方法层面的增强),对某方法进行增强的代码(切面类)(暂且这样理解)
   Introduction:类层面的增强
   Target:被增强的对象
   Waving:织入,将Advice应用到Target的过程----------》形成
   Proxy(代理对象)
   Aspect:切面,多个通知和多个切入点的组合

三、AOP的XML形式开发
1.首先导入jar包:编写IOC的jar包+ aspectj.weaver(依赖包中) + spring-aspects

aspectjrt.jar
aspectjweaver.jar
aspectj.jar
aopalliance.jar
2.添加配置文件applicationContext.xml—>aop约束
3.编写目标类(需要被增强的类)
4.编写测试类
5.编写切面类,类中编写各种方法(如权限校验等等)
6. 在配置文件中用标签配置目标类和切面类(交给spring)
7.对目标生成代理:(切入点+通知)

<aop:config>
//需要增强的方法(切入点)
 <aop:pointcut expression="execution(* 包名.类名.方法名(..))" id="">//注*表示任意返回值,..任意参数;
 //配置切面
 <aop:aspect ref="切面类id">
    //前置通知
   <aop:before method="(通知,即增强的方法)切面类中的方法名" pointcut-ref="(需要增强的方法)切入点id">
 </aop:aspect>
</aop:config>

8.运行
Spring AOP实现方式有两种,一种使用JDK动态代理,另一种通过CGLIB来为目标对象创建代理。如果被代理的目标实现了至少一个接口,则会使用JDK动态代理,所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理,创建的代理类是目标类的子类。
(目标类实现了接口,则通过工程获取对象时,类型为接口类型)

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Users user = (Users) ac.getBean("user");
user.save();

注:其实spring的声明式事务也是通过aop实现的,切入点就比如dao中的各种增删改查方法,当然配置事务管理
不需要我们编写切面类,因为spring中就有一个事务管理器。
当然配置略有不同,如下:缓存了<aop:advisor / >,其他保持一致。

<!-- 会重复读,不会脏读事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" timeout="120" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>

<aop:config proxy-target-class="true">
<aop:pointcut id="txPointCut" expression="..."/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />
</aop:config>

四、通知的类型
前置通知:在目标方法之前进行操作
获得切入点信息 切面类中对应方法传入(JoinPoint类型参数)

后置通知:在目标方法之后进行通知
获得切入点信息和获得方法的返回值
<aop:after-returning method="" pointcut-ref="" returning=“Rname”>
切面类中对应方法传入Object Rname

环绕通知:在目标方法之前和之后进行操作
阻止目标方法的执行

 <aop:around method="" pointcut-ref="">   
 public Object fname(ProceedingJoinPoint joinPoint)throw Throwable{
	   前代码
	   Object obj = JoinPoint.proceed();//相当于执行方法代码
	   后代码
	   return obj;
	   
   }	

例:public Object aopMethod1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println(“切面类方法1执行。。。”);
Object obj = joinPoint.proceed();
System.out.println(“切面类方法2执行。。。”);
return obj;
}

异常抛出通知:在程序出现异常时进行操作

获取异常信息:切面类中对应方法传入 Throwable Tname---->getMseeage();

最终通知: 无论代码是否异常均执行

引介通知:略

五、表达式
表达式的写法灵活且强调
基于execution();
语法:[访问控制符] 方法返回值 包名.方法名(参数)
举例:public void lin.zd.save(…)//…代表任意参数
* ... Dao.save(…)//*代表任意
*.lin.zd.Dao+.save(…)//+代表类和子类
* com.test.spring .(…)

六、个人对于切面编程的理解
在不改原有代码的情况下,对代码进行修改,在代码前后进行增加操作的编程。
因为有可能很多修改的是一样的,所以切面编程只需修改一份。
就好比对代码横向切一刀,然后补入代码。

七、AOP的注解形式开发
1.导jar包,与上面相同
2.xml配置文件,aop约束头
在配置文件中开启注解的开发方式aop:aspectj-autoproxy/
切面类、目标类的注册()
3.在切面类进行注解:
在类名上:@Aspect表示该类为切面类
在切面类方法上(前置增强为例):@Before(value=“execution(”")")

@Aspect
public class myAspect {

@Before(value=“execution(* Lin.zd.targetCls.target.show(…))”)
public void aspectf1() {
System.out.println(“增强方法执行。。。”);
}

}

<?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:aop="http://www.springframework.org/schema/aop" 
	xsi:schemaLocation="
     http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> 

<aop:aspectj-autoproxy/>

<bean id="target" class="Lin.zd.targetCls.target"></bean>//目标类
<bean id="aspect" class="Lin.zd.aspect.myAspect"></bean>//切面类
</beans>

使用:
1.xml方式:
ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);
target tg = (target)ac.getBean(“target”);
tg.show();

2.当然,如果采用组件扫描的方式,可以在切面类上加上@Component来作为扫描的类。

注:1)通知的类型
@Before()
@AfterReturning
@Around
@AfterThrowing("",throwing=“e”)
方法传入参数throwable e
@After

2)@Pointcut(value="execution()")
   空方法如private void p(){}
   
   然后@Before(value="切面类名.p()")
   
   这样便于修改

八、jdcd模板
(一)(这里使用了数据库连接池)
1.导包,(这里使用mysql,这里使用spring自带的连接池所以不用导)
基本的6个包+mysql驱动包+springjdbc的包+spring tx的包
2.获取数据库连接池,再用JdbcTemplate继续操作。

    DriverManagerDataSource ds = new DriverManagerDataSource();
	ds.setDriverClassName("com.mysql.jdbc.Driver");
	ds.setUrl("jdbc:mysql:///hellospring?serverTimezone=UTC");
	ds.setUsername("root");
	ds.setPassword("1234");
	JdbcTemplate jTemplate  = new JdbcTemplate(ds);
	jTemplate.update("insert into account values(null,?,?) ", "李华",1000d);

(二)可以使用配置文件的形式对进行优化
1.数据库连接池的创建交给spring






2.jdbc模板也交给配置文件

https://www.w3cschool.cn/wkspring/iuck1mma.html4
具体使用可以查看:https://www.w3cschool.cn/wkspring/iuck1mma.html

配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">

   <!-- Initialization for data source -->
   <bean id="dataSource" 
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/TEST"/>
      <property name="username" value="root"/>
      <property name="password" value="password"/>
   </bean>

   <!-- Definition for studentJDBCTemplate bean -->
   <bean id="studentJDBCTemplate" 
      class="com.tutorialspoint.StudentJDBCTemplate">
      <property name="dataSource"  ref="dataSource" />    
   </bean>
   
  </beans>

补充1:
spring bean 三种配置方式:

一、spring所需的一些基本依赖

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <!--这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心 -->
      <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <!--这个jar文件为Spring核心提供了大量扩展 -->
      <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <!--对JUNIT等测试框架的简单封装 -->
      <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <!--为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。-->
      <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <!--这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行(IoC/DI)操作相关的所有类 -->
      <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <!--这个jar文件包含对Spring对JDBC数据访问进行封装的所有类。 -->
      <version>4.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

二、配置方式

1.基于XML的配置方式

1)编写Java Bean的 ".java"类,如beanDemo.java.
2)在applicationContext.xml的文件中声明,如下:

<?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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">
	
    <bean id="idName" class="全类名" />

</beans>

3)使用,如:

        ApplicationContext ctx= new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanFactory bean=(BeanFactory) ctx.getBean("idName");
        bean.method(); //使用bean,method()为具体方法

2.基于java注解的配置
1)类使用了@Service,@Component、@Repository、@Controller
,说明该类为bean
2)在xml配置表扫描器,就可以扫描相应包下的类,有注解的类就是bean
<context:component-scan base-package=“包名”/>
3)使用,对于这种方式的使用,可以和基于Xml的使用方式一样,但是注解上需要写bean的名字,如@service(“beanName”)
使用getBean(“beanName”)获取;

  还有一种方式是注解方式的自动装配。

3.基于类的java config(这种方式可以消除xml文件的配置)

1)比如有:接口Bean.java与其实现类 beanImpl.java
2)写一个类作为配置类,如BeanConFig.java,在类上注解@Configuration,该类就相当于xml文件了,在该类中的方法上
  注解@Bean,则说明该方法返回bean,如下:
@Configuration
public class BeanConfig {
    @Bean
    public Bean beanFactory(){
        return new BeanImpl();
    }
}

3)使用

   ApplicationContext applicationContext=new AnnotationConfigApplicationContext(BeanConfig.class);
   Bean bean=applicationContext.getBean(BeanImpl.class);
   bean.method();  

spring事务管理分为编程式事务管理和声明式事务管理,具体用法详见W3Cschool网址
https://www.w3cschool.cn/wkspring/jcny1mmg.html

=============================================================================================
补充2:
spring与springMVC:
子容器的几个特点:
子容器能访问到父容器的bean
父容器无法访问子容器的bean

所以经常是在spring的xml配置全局扫描包(不包括@Controller),而在springMVC的xml中配置@Controller扫描

  <context:component-scan base-package="com.example">
  <context:exclude-filter type="annotation" expression="com.example.annotation.ExcludedFromITests"/>
  </context:component-scan>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值