探索SSM(二)-Spring

Spring

注意~~

①必须在所有使用了dao的地方,包括调用它的servcie都要进行@Autowired注入,否则之后的注入就会失败..
②注解静态实例对象
在Springframework里,我们是不能@Autowired一个静态变量。类加载后静态成员是在内存的共享区,因为当类加载器加载静态变量时,Spring上下文尚未加载。所以类加载器不会在bean中正确注入静态类,并且会失败。
解决方法
方式一:初始化到非静态对象再赋值

@Component
public class TestClass {

   private static AutowiredTypeComponent component;

   @Autowired
   private AutowiredTypeComponent autowiredComponent;

   @PostConstruct
   private void beforeInit() {
      component = this.autowiredComponent;
   }

   // 调用静态组件的方法
   public static void testMethod() {
      component.callTestMethod();
   }

}

方式二:直接用Spring框架工具类获取bean,定义成局部变量使用。

public class TestClass {

    // 调用静态组件的方法
   public static void testMethod() {
      AutowiredTypeComponent component = SpringApplicationContextUtil.getBean("component");
      component.callTestMethod();
   }

}

Spring优势
方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护交给 Spring 管理
AOP 编程的支持
Spring 提供面向切编程,可以方便的实现对序进行权限拦截、运监控等功能 提供面向切编程
声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无手动编程

web.xml

<!--  每次请求都会创建一个工厂类 次请求都会创建一个工厂类 ,服务器端的资源就浪费了 ,一般情况下一个工程只有Spring 的工厂 类就OK 了. * 将工厂在服务器启动的时候创建好 ,将这个工厂放入到 ServletContext 域中 .每次获取工厂从 ServletContext 域中进行获取  -->
配置监听器 : 
<listener >
    <listener -class >org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
<context -param >
    <param-name >contextConfigLocation </param-name >
    <param-value >classpath:applicationContext.xml </param-value >
</context-param >

getBean操作

WebApplicationContext applicationContext = WebApplicationContextUtils. getWebApplicationContext (ServletActionContext. getServletContext()); 
CustomerService customerService = (CustomerService) applicationContext .getBean( "customerService" ); 

3.5.5. applicationContext-service.xml

配置注解扫描

<! -- Spring 的注解开发 :组件扫描 (类上注解 : 可以直接使用属性注入的解 可以直接使用属性注入的解 ) -- >
<context:component -scan base -package="com.itheima.spring.demo1"/>

引入外部属性文件

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

在相关的类上添加注解 :

@Component (value= "userDao ") public class UserDaoImpl implements UserDao { 

    @Override public void sayHello() { 
        System. out .println( "Hello Spring Annotation ..." );
        } 
    }

注解解释
1.2.2.1 Spring 中提供 @Component 的三个衍生注解 :( **功能目前来讲是一致的 **)
@Controller :WEB 层 *
@Service :业务层 业务层 *
@Repository :持久层 持久层
这三个注解是为了让标类本身的用途清晰

1.2.2.2 注解的属性
@Value :用于注入普通类型 .
@Autowired :自动装配 :
* 默认按类型进行装配
* 按名称注入 按名称注入 :
* @Qualifier: 强制使用名称注入 .
@Resource 相当于 相当于 : * @Autowired 和@Qualifier 一起使用 .

1.2.2.3 Bean 的作用范围注解 :
@Scope:
* singleton: 单例
* prototype: 多例

1.2.2.4 Bean的生命周期配置:
@PostConstruct :相当于 init-method
@PreDestroy :相当于 destroy-method

AOP(applicationContext-trans.xml)

底层代理机制 :
Spring 的 AOP 的底层用到两种代理机制:
* JDK 的动态代理 :针对实现了接口的类产生代理 .
* Cglib 的动态代理 :针对没有实现接口的类产生代理 应用的是底层字节码增强技术, 生成当前类的子类对象 .

注解解释
Joinpoint(连接点): 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点. Pointcut(切入点): 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
Advice(通知/增强): 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Introduction(引介): 引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field. Target(目标对象): 代理的目标对象
Weaving(织入): 是指把增强应用到目标对象来创建新的代理对象的过程.
spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
Proxy(代理): 一个类被AOP织入增强后,就产生一个结果代理类 Aspect(切面): 是切入点和通知(引介)的结合

1.2.7.6 通知类型
@Before 前置通知 :在目标方法执行之前执行
@AfterReturing 后置通知 :在目标方法执行之后执行
@Around 环绕通知 :在目标方法执行前和后执行
@After 异常抛出通知:在目标方法执行出现异常的时候执行
@AfterThrowing 最终通知 :无论目标方法是否出现异常最终通知都会执行

AspectJ进行AOP开发 :XML的方式

1.2.7.7 切入点表达式

execution( 表达式 )
表达式 : 
[方法访问修饰符] 方法返回值 包名 .类名 .方法名 (方法的参数 ) 
public * cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.UserDao+.*(..) *

1.2.7.8 编写一个切面类

    public class MyAspectXml {
         // 前置增强
        public void before(){
            System. out .println( "前置增强 ===========" ); 
        } 
    }

1.2.7.9 配置完成增强

<! -- 配置切面类 -- >
<bean id ="myAspectXml" class ="cn.itcast.spring.demo3.MyAspectXml" ></ bean >

<! -- 进行 aop 的配置 -- >
<aop:config >
    <! -- 配置切入点表达式 :哪些类的方法需要进行增强 哪些类的方法需要进行增强 -- >
    <aop:pointcut expression ="execution(* cn.itcast.spring.demo3.O rderDao.save(..))" id ="pointcut1" />
    <! -- 配置切面 -- >
    <aop:aspect ref ="myAspectXml" >
        <aop:before method ="before" pointcut -ref ="pointcut1" />
    </ aop:aspect >
</ aop:config >
AspectJ进行AOP开发 :注解的方式(常规)

1.2.1.5 开启 aop 注解的自动代理 :
<aop:aspectj -autoproxy/>

1.2.1.8 配置切面 :
<! -- 配置切面类 -- >
<bean id ="myAspectAnno" "myAspectAnno" class ="cn.itcast.spring.demo4.MyAspectAnno" ></ bean >

1.2.1.9 编写切面类

@Aspect
public class MyAspectAnno { 
@Before ("MyAspectAnno.pointcut1()" )
    public void before(){
        System. out .println( "前置通知 ===========" ); 
    } 

@AfterReturning ("MyAspectAnno.pointcut2()" ) 
    public void afterReturning(){
        System. out .println( "后置通知 ===========" ); 
    }

@Around ("MyAspectAnno.pointcut3()" ) 
    public Object around(ProceedingJoinPoint joinPoint ) throws Throwable{
     System. out .println( "环绕前通知 ==========" );
     Object obj = joinPoint .proceed();
     System. out .println( "环绕后通知 ==========" );
     return obj ; 
     } 

@AfterThrowing ("MyAspectAnno.pointcut4()" ) public void afterThrowing(){
    System. out .println( "异常抛出通知 ========" ); 
    }

@After ("MyAspectAnno.pointcut4()" ) 
    public void after(){
    System. out .println( "最终通知 ==========" ); 
    } 

@Pointcut ("execution(* cn.itcast.spring.demo4.ProductDao.save(..))" )
     private void pointcut1(){}
@Pointcut ("execution(* cn.itcast.spring.demo4.ProductDa o.update(..))" )
    private void pointcut2(){}
@Pointcut ("execution(* cn.itcast.spring.demo4.ProductDao.delete(..))" )
     private void pointcut3(){}
@Pointcut ("execution(* cn.itcast.spring.demo4.ProductDao.find(..))" )
     private void pointcut4(){} }

Spring事务管理

连接池的配置
①内置连接池

<-- 配置 Spring 的内置连接池 -- >
<bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource" >
    <property name ="driverClassName" value ="com.mysq l.jdbc.Driver" />
    <property name ="url" value ="jdbc:mysql:///spring_day02" />
    <property name ="username" value ="root" />
    <property name ="password" value ="123" />
</ bean >

②DBCP连接池

<-- 配置 DBCP 连接池 -- >
<bean id ="dataSource" "dataSource" class ="org.apache.commons.dbcp.BasicDataSource" >
    <property name ="driverClassName" value ="com.mysql.jdbc.Driver" />
    <property name ="url" value ="jdbc:mysql:///spring_day02" />
    <property name ="username" value ="root" />
    <property name ="password" value ="123" />
</ bean >

③c3p0连接池

<! -- 配置 C3P0 连接池 -- >
<bean id ="dataSource" "dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource" >
    <property name ="driverClass" value ="com.mysql.jdbc.Driver" />
    <property name ="jdbcUrl" value ="jdbc:mysql:///spring_day02" />
    <property name ="user" value ="root" />
    <property name ="password" value ="123" />
</ bean >

事务的传播行为

保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常 

保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行

1.5.2 Spring的编程式事务-手动编写

ggg.png

1.5.3 Spring的声明式事务管理:XML 方式

1.5.3.3 配置事务管理器

<-- 事务管理器 -- >
<bean id ="transactionManager" class ="org.sp ringframework.jdbc.datasource.DataSourceTransactionManager" >
    <property name ="dataSource" ref ="dataSource" />
</ bean >

1.5.3.4 配置事务的通知

<! -- 配置事务的增强 -- >
<tx:advice id ="txAdvice" "txAdvice" transaction -manager ="transactionManager" >
    <tx:attributes > <! -- isolation="DEFAULT" 隔离级别 propagation="REQUIRED" 传播行为 read -only="false" 只读 timeout=" -1" 过期时间 rollback -for="" -Exception no -rollback -for="" +Exception -- >
        <tx:method name ="transfer" propagation ="REQUIRED" />
    </ tx:attributes >
</ tx:advice >

1.5.3.5 配置 aop 事务
<aop:config >
<aop:pointcut expression ="execution(* cn.itcast.transaction.demo2.AccountServiceImpl.transfer(..))" id ="pointcut1" />
<aop:advisor advice -ref ="txAdvice" pointcut -ref ="pointcut1" />
</ aop:config >

1.5.3 Spring的声明式事务管理:注解方式

1.5.4.1 引入 jar包:


hhh.jpg

1.5.4.3 配置事务管理器 :

<! -- 配置事务管理器 -- >
<bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
    <property name ="dataSource" ref ="dataSource" />
</bean >

1.5.4.4 开启事务管理的注解 :

<! -- 开启注解事务管理 -- >
<tx:annotation -driven transaction -manager ="transactionManager" />

1.5.4.5 在使用事务的类上添加一个注解: @Transactional


ppp.jpg

e.g. 本文仅供个人笔记使用,借鉴部分网上资料。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 12,212评论 6 86
  • 本章内容: 面向切面编程的基本原理 通过POJO创建切面 使用@AspectJ注解 为AspectJ切面注入依赖 ...
    谢随安阅读 3,058评论 0 9
  • 什么是Spring Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Jav...
    jemmm阅读 16,360评论 1 133
  • 一场春雪,白了梨花 我对着漫天冰雪无声的喊话 它却从不回答 一枝枯柳,绿了新芽 我对着满目春色轻轻的敲打 它却径自...
    夜落羽花阅读 138评论 0 2
  • 野寂元明色,泊舟淡净心。 孤吟寻旷逸,悦目醉秋深。 (中华新韵·九文)
    不惑而歌阅读 1,278评论 16 45