@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ā)的淤翔。
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>