Spring學(xué)習(xí)(一)

@Service场勤,@Repository

一:@Service婚瓜,@Repository不能寫(xiě)在接口上狰贯,需要寫(xiě)在接口的實(shí)現(xiàn)類(lèi)上幸逆。
二:@Autowired注入的時(shí)候,可以用接口注入暮现,也可以用接口的實(shí)現(xiàn)類(lèi)注入还绘。
三:如果使用接口注入,并且接口有多個(gè)實(shí)現(xiàn)類(lèi)栖袋,那么必須配合@Qualifier(value = “bean別名”)使用拍顷,指定具體的bean,需要在注入的實(shí)現(xiàn)類(lèi)上面加上別名塘幅,例如@Repository(“accountDaoImpl”)

@Resource

先進(jìn)行byName查找昔案,失敗电媳;再進(jìn)行byType查找

public class User {
  //如果允許對(duì)象為null踏揣,設(shè)置required = false,默認(rèn)為true
  @Resource(name = "cat2")
  private Cat cat;
  @Resource
  private Dog dog;
  private String str;
}
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>

@Autowired先byType,@Resource先byName

DI

常用的注入方式主要有三種:構(gòu)造方法注入(Construct注入)匾乓,setter注入捞稿,基于注解的注入(接口注入)

注解注入:

  • constructor:通過(guò)構(gòu)造方法進(jìn)行自動(dòng)注入,spring會(huì)匹配與構(gòu)造方法參數(shù)類(lèi)型一致的bean進(jìn)行注入拼缝,如果有一個(gè)多參數(shù)的構(gòu)造方法娱局,一個(gè)只有一個(gè)參數(shù)的構(gòu)造方法,在容器中查找到多個(gè)匹配多參數(shù)構(gòu)造方法的bean咧七,那么spring會(huì)優(yōu)先將bean注入到多參數(shù)的構(gòu)造方法中衰齐。
  • byName:被注入bean的id名必須與set方法后半截匹配,并且id名稱(chēng)的第一個(gè)單詞首字母必須小寫(xiě)继阻,這一點(diǎn)與手動(dòng)set注入有點(diǎn)不同耻涛。
  • byType:查找所有的set方法废酷,將符合符合參數(shù)類(lèi)型的bean注入。
@Service
public class UserServiceImpl {

    /**
     * user dao impl.
     */
    @Autowired
    private UserDaoImpl userDao;

    /**
     * find user list.
     *
     * @return user list
     */
    public List<User> findUserList() {
        return userDao.findUserList();
    }

}

AOP

  • 動(dòng)態(tài)織入的方式是在運(yùn)行時(shí)動(dòng)態(tài)將要增強(qiáng)的代碼織入到目標(biāo)類(lèi)中抹缕,這樣往往是通過(guò)動(dòng)態(tài)代理技術(shù)完成的澈蟆,如Java JDK的動(dòng)態(tài)代理(Proxy,底層通過(guò)反射實(shí)現(xiàn))或者CGLIB的動(dòng)態(tài)代理(底層通過(guò)繼承實(shí)現(xiàn))歉嗓,Spring AOP采用的就是基于運(yùn)行時(shí)增強(qiáng)的代理技術(shù)

  • ApectJ采用的就是靜態(tài)織入的方式丰介。ApectJ主要采用的是編譯期織入,在這個(gè)期間使用AspectJ的acj編譯器(類(lèi)似javac)把a(bǔ)spect類(lèi)編譯成class字節(jié)碼后鉴分,在java目標(biāo)類(lèi)編譯時(shí)織入哮幢,即先編譯aspect類(lèi)再編譯目標(biāo)類(lèi)。

Spring AOP 支持對(duì)XML模式和基于@AspectJ注解的兩種配置方式

package tech.pdai.springframework.aspect;

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;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @author pdai
 */
@EnableAspectJAutoProxy
@Component
@Aspect
public class LogAspect {

    /**
     * define point cut.
     */
    @Pointcut("execution(* tech.pdai.springframework.service.*.*(..))")
    private void pointCutMethod() {
    }


    /**
     * 環(huán)繞通知.
     *
     * @param pjp pjp
     * @return obj
     * @throws Throwable exception
     */
    @Around("pointCutMethod()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("-----------------------");
        System.out.println("環(huán)繞通知: 進(jìn)入方法");
        Object o = pjp.proceed();
        System.out.println("環(huán)繞通知: 退出方法");
        return o;
    }

    /**
     * 前置通知.
     */
    @Before("pointCutMethod()")
    public void doBefore() {
        System.out.println("前置通知");
    }


    /**
     * 后置通知.
     *
     * @param result return val
     */
    @AfterReturning(pointcut = "pointCutMethod()", returning = "result")
    public void doAfterReturning(String result) {
        System.out.println("后置通知, 返回值: " + result);
    }

    /**
     * 異常通知.
     *
     * @param e exception
     */
    @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
    public void doAfterThrowing(Exception e) {
        System.out.println("異常通知, 異常: " + e.getMessage());
    }

    /**
     * 最終通知.
     */
    @After("pointCutMethod()")
    public void doAfter() {
        System.out.println("最終通知");
    }

}

out

-----------------------
環(huán)繞通知: 進(jìn)入方法
前置通知
JdkProxyServiceImpl.doMethod1()
最終通知
環(huán)繞通知: 退出方法
-----------------------
環(huán)繞通知: 進(jìn)入方法
前置通知
JdkProxyServiceImpl.doMethod2()
后置通知, 返回值: hello world
最終通知
環(huán)繞通知: 退出方法
-----------------------
環(huán)繞通知: 進(jìn)入方法
前置通知
JdkProxyServiceImpl.doMethod3()
異常通知, 異常: some exception
最終通知
------

pointcut

// 任意公共方法的執(zhí)行:
execution(public * *(..))

// 任何一個(gè)名字以“set”開(kāi)始的方法的執(zhí)行:
execution(* set*(..))

// AccountService接口定義的任意方法的執(zhí)行:
execution(* com.xyz.service.AccountService.*(..))

// 在service包中定義的任意方法的執(zhí)行:
execution(* com.xyz.service.*.*(..))

// 在service包或其子包中定義的任意方法的執(zhí)行:
execution(* com.xyz.service..*.*(..))

// 在service包中的任意連接點(diǎn)(在Spring AOP中只是方法執(zhí)行):
within(com.xyz.service.*)

// 在service包或其子包中的任意連接點(diǎn)(在Spring AOP中只是方法執(zhí)行):
within(com.xyz.service..*)

// 實(shí)現(xiàn)了AccountService接口的代理對(duì)象的任意連接點(diǎn) (在Spring AOP中只是方法執(zhí)行):
this(com.xyz.service.AccountService)// 'this'在綁定表單中更加常用

// 實(shí)現(xiàn)AccountService接口的目標(biāo)對(duì)象的任意連接點(diǎn) (在Spring AOP中只是方法執(zhí)行):
target(com.xyz.service.AccountService) // 'target'在綁定表單中更加常用

// 任何一個(gè)只接受一個(gè)參數(shù)志珍,并且運(yùn)行時(shí)所傳入的參數(shù)是Serializable 接口的連接點(diǎn)(在Spring AOP中只是方法執(zhí)行)
args(java.io.Serializable) // 'args'在綁定表單中更加常用; 請(qǐng)注意在例子中給出的切入點(diǎn)不同于 execution(* *(java.io.Serializable)): args版本只有在動(dòng)態(tài)運(yùn)行時(shí)候傳入?yún)?shù)是Serializable時(shí)才匹配橙垢,而execution版本在方法簽名中聲明只有一個(gè) Serializable類(lèi)型的參數(shù)時(shí)候匹配。

// 目標(biāo)對(duì)象中有一個(gè) @Transactional 注解的任意連接點(diǎn) (在Spring AOP中只是方法執(zhí)行)
@target(org.springframework.transaction.annotation.Transactional)// '@target'在綁定表單中更加常用

// 任何一個(gè)目標(biāo)對(duì)象聲明的類(lèi)型有一個(gè) @Transactional 注解的連接點(diǎn) (在Spring AOP中只是方法執(zhí)行):
@within(org.springframework.transaction.annotation.Transactional) // '@within'在綁定表單中更加常用

// 任何一個(gè)執(zhí)行的方法有一個(gè) @Transactional 注解的連接點(diǎn) (在Spring AOP中只是方法執(zhí)行)
@annotation(org.springframework.transaction.annotation.Transactional) // '@annotation'在綁定表單中更加常用

// 任何一個(gè)只接受一個(gè)參數(shù)伦糯,并且運(yùn)行時(shí)所傳入的參數(shù)類(lèi)型具有@Classified 注解的連接點(diǎn)(在Spring AOP中只是方法執(zhí)行)
@args(com.xyz.security.Classified) // '@args'在綁定表單中更加常用

// 任何一個(gè)在名為'tradeService'的Spring bean之上的連接點(diǎn) (在Spring AOP中只是方法執(zhí)行)
bean(tradeService)

// 任何一個(gè)在名字匹配通配符表達(dá)式'*Service'的Spring bean之上的連接點(diǎn) (在Spring AOP中只是方法執(zhí)行)
bean(*Service)

MVC

Spring Web MVC 是一種基于Java 的實(shí)現(xiàn)了Web MVC 設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類(lèi)型的輕量級(jí)Web 框架柜某,即使用了MVC 架 構(gòu)模式的思想,將 web 層進(jìn)行職責(zé)解耦敛纲,基于請(qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型喂击,框架的目的就是幫助我們簡(jiǎn)化開(kāi) 發(fā),Spring Web MVC 也是要簡(jiǎn)化我們?nèi)粘eb 開(kāi)發(fā)的淤翔。


mvc

Controller

package tech.pdai.springframework.springmvc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import tech.pdai.springframework.springmvc.service.UserServiceImpl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * User Controller.
 *
 * @author pdai
 */
@Controller
public class UserController {

    @Autowired
    private UserServiceImpl userService;

    /**
     * find user list.
     *
     * @param request  request
     * @param response response
     * @return model and view
     */
    @RequestMapping("/user")
    public ModelAndView list(HttpServletRequest request, HttpServletResponse response) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("dateTime", new Date());
        modelAndView.addObject("userList", userService.findUserList());
        modelAndView.setViewName("userList"); // views目錄下userList.jsp
        return modelAndView;
    }
}

userList.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>User List</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" >

</head>
<body>
    <div class="container">
        <c:if test="${!empty userList}">
            <table class="table table-bordered table-striped">
                <tr>
                    <th>Name</th>
                    <th>Age</th>
                </tr>
                <c:forEach items="${userList}" var="user">
                    <tr>
                        <td>${user.name}</td>
                        <td>${user.age}</td>
                    </tr>
                </c:forEach>
            </table>
        </c:if>
    </div>
</body>
</html>

springmvc.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 掃描注解 -->
    <context:component-scan base-package="tech.pdai.springframework.springmvc"/>

    <!-- 靜態(tài)資源處理 -->
    <mvc:default-servlet-handler/>

    <!-- 開(kāi)啟注解 -->
    <mvc:annotation-driven/>

    <!-- 視圖解析器 -->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>SpringFramework - SpringMVC Demo @pdai</display-name>

    <servlet>
        <servlet-name>springmvc-demo</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 通過(guò)初始化參數(shù)指定SpringMVC配置文件的位置和名稱(chēng) -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc-demo</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末翰绊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子旁壮,更是在濱河造成了極大的恐慌监嗜,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抡谐,死亡現(xiàn)場(chǎng)離奇詭異裁奇,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)麦撵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)刽肠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人厦坛,你說(shuō)我怎么就攤上這事五垮。” “怎么了杜秸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)润绎。 經(jīng)常有香客問(wèn)我撬碟,道長(zhǎng)诞挨,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任呢蛤,我火速辦了婚禮惶傻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘其障。我一直安慰自己银室,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布励翼。 她就那樣靜靜地躺著蜈敢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪汽抚。 梳的紋絲不亂的頭發(fā)上抓狭,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音造烁,去河邊找鬼否过。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惭蟋,可吹牛的內(nèi)容都是我干的苗桂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼告组,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼煤伟!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起惹谐,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤持偏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后氨肌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸿秆,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年怎囚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卿叽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恳守,死狀恐怖考婴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情催烘,我是刑警寧澤沥阱,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站伊群,受9級(jí)特大地震影響考杉,放射性物質(zhì)發(fā)生泄漏策精。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一崇棠、第九天 我趴在偏房一處隱蔽的房頂上張望咽袜。 院中可真熱鬧,春花似錦枕稀、人聲如沸询刹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)凹联。三九已至,卻和暖如春食铐,著一層夾襖步出監(jiān)牢的瞬間匕垫,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工虐呻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留象泵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓斟叼,卻偏偏與公主長(zhǎng)得像偶惠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朗涩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容