0. 緒論
在第二天的學習中的學習JdbcTemplate之前,想要下載最新版本的mysql server8.0.11 結果在將所有的東西配置好后,發現報錯,
?
Cannot?create?PoolableConnectionFactory?(Could?not?create?connection?to?database?server.)
?后來發現可能是spring框架的驅動版本太低,將新版本的換成舊版本的mysql server 5.5.40后就沒有問題了,由于在找這個問題的時候花費了太多時間就沒有心情去換新版本的了,也由于看的視頻是比較早的視頻,很多驅動的包都是比較低 的版本,所以想著以后有時間了在將所有的軟件和驅動都換成最新的版本。
1?????? spring day01回顧
1.1?? 編寫流程(基于xml)
1.導入jar包:4+1? --> beans/core/context/expression? | commons-logging
2.編寫目標類:dao和service
3.spring配置文件
SpringMVC。IoC:<bean id="" class="" > DI:<bean> <property name="" value="" | ref=""> 實例化方式: ? 默認構造 ? 靜態工廠:<bean id="" class="工廠類" factory-method="靜態方法"> ? 實例工廠:<bean id="工廠id" class="工廠類">? <bean id="" factory-bean="工廠id" factory-method="方法"> Spring Framework、作用域:<bean id="" class="" scope="singleton | prototype"> 生命周期:<bean id="" class="" init-method="" destroy-method=""> ? 后處理bean? BeanPostProcessor接口,<bean class="注冊"> ,對容器中所有的bean都生效 屬性注入 ? 構造方法注入:<bean><constructor-arg index="" type="" > ? setter方法注入:<bean><property> java框架教學,? p命名空間:簡化<property>?? <bean p:屬性名="普通值"? p:屬性名-ref="引用值">? 注意聲明命名空間 ? SpEL:<property name="" value="#{表達式}"> ???? #{123}? #{'abc'} ???? #{beanId.propName?.methodName()} ???? #{T(類).靜態方法|字段} ? 集合 spring模塊,???? 數組<array> ???? List <list> ???? Set <set> ???? Map <map><entry key="" value=""> ???? Properties <props><prop key="">.... |
IoC:
Spring boot。4.核心api
?????? BeanFactory,延遲實例化bean,第一次調用getBean
?????? ApplicationContext 一般常用,功能更強
????????????? ClassPathXmlApplicationContext 加載classpath xml文件
????????????? FileSystemXmlApplicationContext 加載指定盤符文件 , ServletContext.getRealPath()
?
1.2?? 后處理bean 對一個生效
@Override ??? public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { ??? ??? if("userServiceId".equals(beanName)){ ??????????? System.out.println("前方法 : " + beanName); ??????? } ??????? return bean; Springboot教程。??? } |
?
1.3?? 注解
1.掃描含有注解的類
?????? <context:component-scan base-package="....">
2.常見的注解
?????? @Component? 組件,任意bean
spring框架要學多久。?????? WEB
????????????? @Controller? web層
????????????? @Service service層
????????????? @Repository dao層
?????? 注入? --> 字段或setter方法
????????????? 普通值:@Value
spring入門教程。????????????? 引用值:
???????????????????? 類型:@Autowired
???????????????????? 名稱1:@Autowired? @Qualifier("名稱")
???????????????????? 名稱2:@Resource("名稱")
?????? 作用域:@Scope("prototype")
?????? 生命周期:
spring開發框架、????????????? 初始化:@PostConstruct
????????????? 銷毀方法:@PreDestroy
?
1.4?? 注解和xml混合使用
1.將所有的bean都配置xml中
?????? <bean id="" class="">
2.將所有的依賴都使用注解
java多線程、?????? @Autowired
?????? 默認不生效。為了生效,需要在xml配置:<context:annotation-config>
?
總結:
注解1:<context:component-scan base-package=" ">
注解2:<context:annotation-config>
spring框架干什么用的?1.一般情況兩個注解不一起使用。
2. “注解1”掃描含有注解(@Component 等)類,注入注解自動生效。
?????? “注解2”只在xml和注解(注入)混合使用時,使注入注解生效。
?
?
?
2?????? AOP
2.1?? AOP介紹
2.1.1?? 什么是AOP
jeecg框架入門、l? 在軟件業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP(面向對象編程)的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
l? AOP采取橫向抽取機制,取代了傳統縱向繼承體系重復性代碼
l? 經典應用:事務管理、性能監視、安全檢查、緩存 、日志等
l? Spring AOP使用純Java實現,不需要專門的編譯過程和類加載器,在運行期通過代理方式向目標類織入增強代碼
l? AspectJ是一個基于Java語言的AOP框架,Spring2.0開始,Spring AOP引入對Aspect的支持,AspectJ擴展了Java語言,提供了一個專門的編譯器,在編譯時提供橫向代碼的織入
?
java都有什么框架??
2.1.2?? AOP實現原理
l? aop底層將采用代理機制進行實現。
l? 接口 + 實現類 :spring采用 jdk 的動態代理Proxy。
l? 實現類:spring 采用 cglib字節碼增強。
?
?
2.1.3?? AOP術語【掌握】
Spring MVC,1.target:目標類,需要被代理的類。例如:UserService
2.Joinpoint(連接點):所謂連接點是指那些可能被攔截到的方法。例如:所有的方法
3.PointCut 切入點:已經被增強的連接點。例如:addUser()
4.advice 通知/增強,增強代碼。例如:after、before
5. Weaving(織入):是指把增強advice應用到目標對象target來創建新的代理對象proxy的過程.
6.proxy 代理類
Springboot框架?7. Aspect(切面): 是切入點pointcut和通知advice的結合
?????? 一個線是一個特殊的面。
?????? 一個切入點和一個通知,組成成一個特殊的面。
?
?
?
2.2?? 手動方式
2.2.1?? JDK動態代理
spring快速入門教程?l? JDK動態代理 對“裝飾者”設計模式 簡化。使用前提:必須有接口
1.目標類:接口 + 實現類
2.切面類:用于存通知 MyAspect
3.工廠類:編寫工廠生成代理
4.測試
?
spring框架是什么。?
2.2.1.1 目標類
public interface UserService { ?? ?? public void addUser(); ?? public void updateUser(); ?? public void deleteUser(); ? } |
?
2.2.1.2 切面類
public class MyAspect { ?? ?? public void before(){ ????? System.out.println("雞首"); ?? } ?? ?? public void after(){ ????? System.out.println("牛后"); ?? } ? } ? |
?
2.2.1.3 工廠
public class MyBeanFactory { ?? ?? public static UserService createService(){ ????? //1 目標類 ????? final UserService userService = new UserServiceImpl(); ????? //2切面類 ????? final MyAspect myAspect = new MyAspect(); ????? /* 3 代理類:將目標類(切入點)和 切面類(通知) 結合 --> 切面 ????? ?* Proxy.newProxyInstance ????? ?* ?? 參數1:loader ,類加載器,動態代理類 運行時創建,任何類都需要類加載器將其加載到內存。 ????? ?* ????? 一般情況:當前類.class.getClassLoader(); ????? ?* ???????????? 目標類實例.getClass().get... ????? ?* ?? 參數2:Class[] interfaces 代理類需要實現的所有接口 ????? ?* ?????? 方式1:目標類實例.getClass().getInterfaces()? ;注意:只能獲得自己接口,不能獲得父元素接口 ????? ?* ?????? 方式2:new Class[]{UserService.class}?? ????? ?* ?????? 例如:jdbc 驅動? --> DriverManager? 獲得接口 Connection ????? ?* ?? 參數3:InvocationHandler? 處理類,接口,必須進行實現類,一般采用匿名內部 ????? ?* ?????? 提供 invoke 方法,代理類的每一個方法執行時,都將調用一次invoke ????? ?* ????????? 參數31:Object proxy :代理對象 ????? ?* ????????? 參數32:Method method : 代理對象當前執行的方法的描述對象(反射) ????? ?* ???????????? 執行方法名:method.getName() ????? ?* ???????????? 執行方法:method.invoke(對象,實際參數) ????? ?* ????????? 參數33:Object[] args :方法實際參數 ????? ?* ????? ?*/ ????? UserService proxService = (UserService)Proxy.newProxyInstance( ???????????????????????? MyBeanFactory.class.getClassLoader(), ???????????????????????? userService.getClass().getInterfaces(), ???????????????????????? new InvocationHandler() { ??????????????????????????? ??????????????????????????? @Override ??????????????????????????? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ?????????????????????????????? ?????????????????????????????? //前執行 ?????????????????????????????? myAspect.before(); ?????????????????????????????? ?????????????????????????????? //執行目標類的方法 ?????????????????????????????? Object obj = method.invoke(userService, args); ?????????????????????????????? ?????????????????????????????? //后執行 ?????????????????????????????? myAspect.after(); ?????????????????????????????? ?????????????????????????????? return obj; ??????????????????????????? } ???????????????????????? }); ????? ????? return proxService; ?? } ? } |
?
?
2.2.1.4 測試
@Test ?? public void demo01(){ ????? UserService userService = MyBeanFactory.createService(); ????? userService.addUser(); ????? userService.updateUser(); ????? userService.deleteUser(); ?? } |
?
?
2.2.2?? CGLIB字節碼增強
l? 沒有接口,只有實現類。
l? 采用字節碼增強框架 cglib,在運行時 創建目標類的子類,從而對目標類進行增強。
l? 導入jar包:
?????? 自己導包(了解):
????????????? 核心:hibernate-distribution-3.6.10.Final\lib\bytecode\cglib\cglib-2.2.jar
????????????? 依賴:struts-2.3.15.3\apps\struts2-blank\WEB-INF\lib\asm-3.3.jar
?????? spring-core..jar 已經整合以上兩個內容
?????????????
??????
?
?
?
?
2.2.2.1 工廠類
public class MyBeanFactory { ?? ?? public static UserServiceImpl createService(){ ????? //1 目標類 ????? final UserServiceImpl userService = new UserServiceImpl(); ????? //2切面類 ????? final MyAspect myAspect = new MyAspect(); ????? // 3.代理類 ,采用cglib,底層創建目標類的子類 ????? //3.1 核心類 ????? Enhancer enhancer = new Enhancer(); ????? //3.2 確定父類 ????? enhancer.setSuperclass(userService.getClass()); ????? /* 3.3 設置回調函數 , MethodInterceptor接口 等效 jdk InvocationHandler接口 ????? ?* intercept() 等效 jdk? invoke() ????? ?* ?? 參數1、參數2、參數3:以invoke一樣 ????? ?* ?? 參數4:methodProxy 方法的代理 ????? ?* ?? ????? ?* ????? ?*/ ????? enhancer.setCallback(new MethodInterceptor(){ ? ???????? @Override ???????? public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { ??????????? ??????????? //前 ??????????? myAspect.before(); ??????????? ??????????? //執行目標類的方法 ??????????? Object obj = method.invoke(userService, args); ??????????? // * 執行代理類的父類 ,執行目標類 (目標類和代理類 父子關系) ??????????? methodProxy.invokeSuper(proxy, args); ??????????? ??????????? //后 ??????????? myAspect.after(); ??????????? ??????????? return obj; ???????? } ????? }); ????? //3.4 創建代理 ????? UserServiceImpl proxService = (UserServiceImpl) enhancer.create(); ????? ????? return proxService; ?? } ? } |
?
?
2.3?? AOP聯盟通知類型
l? AOP聯盟為通知Advice定義了org.aopalliance.aop.Advice l? Spring按照通知Advice在目標類方法的連接點位置,可以分為5類
|
?
環繞通知,必須手動執行目標方法 try{ ?? //前置通知 ?? //執行目標方法 ?? //后置通知 } catch(){ ?? //拋出異常通知 } |
?
2.4?? spring編寫代理:半自動
l? 讓spring 創建代理對象,從spring容器中手動的獲取代理對象。
l? 導入jar包:
?????? 核心:4+1
?????? AOP:AOP聯盟(規范)、spring-aop (實現)
?
?
2.4.1?? 目標類
public interface UserService { ?? ?? public void addUser(); ?? public void updateUser(); ?? public void deleteUser(); ? } |
?
2.4.2?? 切面類
/** ?* 切面類中確定通知,需要實現不同接口,接口就是規范,從而就確定方法名稱。 ?* * 采用“環繞通知” MethodInterceptor ?* ?*/ public class MyAspect implements MethodInterceptor { ? ?? @Override ?? public Object invoke(MethodInvocation mi) throws Throwable { ????? ????? System.out.println("前3"); ????? ????? //手動執行目標方法 ????? Object obj = mi.proceed(); ????? ????? System.out.println("后3"); ????? return obj; ?? } } |
?
?
2.4.3?? spring配置
<!-- 1 創建目標類 --> ??? <bean id="userServiceId" class="com.itheima.b_factory_bean.UserServiceImpl"></bean> ??? <!-- 2 創建切面類 --> ??? <bean id="myAspectId" class="com.itheima.b_factory_bean.MyAspect"></bean> ? ??? <!-- 3 創建代理類 ??????? * 使用工廠bean FactoryBean ,底層調用 getObject() 返回特殊bean ??????? * ProxyFactoryBean 用于創建代理工廠bean,生成特殊代理對象 ??????????? interfaces : 確定接口們 ??????????????? 通過<array>可以設置多個值 ??????????????? 只有一個值時,value="" ??????????? target : 確定目標類 ??????????? interceptorNames : 通知 切面類的名稱,類型String[],如果設置一個值 value="" ??????????? optimize :強制使用cglib ??????????????? <property name="optimize" value="true"></property> ??????? 底層機制 ??????????? 如果目標類有接口,采用jdk動態代理 ??????????? 如果沒有接口,采用cglib 字節碼增強 ??????????? 如果聲明 optimize = true ,無論是否有接口,都采用cglib ??????? ??? --> ??? <bean id="proxyServiceId" class="org.springframework.aop.framework.ProxyFactoryBean"> ??????? <property name="interfaces" value="com.itheima.b_factory_bean.UserService"></property> ??????? <property name="target" ref="userServiceId"></property> ??????? <property name="interceptorNames" value="myAspectId"></property> ??? </bean> |
?
2.4.4?? 測試
?
??? @Test ??? public void demo01(){ ??????? String xmlPath = "com/itheima/b_factory_bean/beans.xml"; ??????? ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); ??????? ??????? //獲得代理類 ??????? UserService userService = (UserService) applicationContext.getBean("proxyServiceId"); ??????? userService.addUser(); ??????? userService.updateUser(); ??????? userService.deleteUser(); ??? } |
?
?
?
?
?
2.5?? spring aop編程:全自動【掌握】
l? 從spring容器獲得目標類,如果配置aop,spring將自動生成代理。
l? 要確定目標類,aspectj 切入點表達式,導入jar包
?????? spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE
?
?
?
2.5.1?? spring配置
?
<?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 ?????? ????????????????? ???http://www.springframework.org/schema/beans/spring-beans.xsd ?????? ????????????????? ???http://www.springframework.org/schema/aop ?????? ????????????????? ???http://www.springframework.org/schema/aop/spring-aop.xsd"> ??? <!-- 1 創建目標類 --> ??? <bean id="userServiceId" class="com.itheima.c_spring_aop.UserServiceImpl"></bean> ??? <!-- 2 創建切面類(通知) --> ??? <bean id="myAspectId" class="com.itheima.c_spring_aop.MyAspect"></bean> ??? <!-- 3 aop編程 ??????? 3.1 導入命名空間 ??????? 3.2 使用 <aop:config>進行配置 ??????????????? proxy-target-class="true" 聲明時使用cglib代理 ??????????? <aop:pointcut> 切入點 ,從目標對象獲得具體方法 ??????????? <aop:advisor> 特殊的切面,只有一個通知 和 一個切入點 ??????????????? advice-ref 通知引用 ??????????????? pointcut-ref 切入點引用 ??????? 3.3 切入點表達式 ??????????? execution(* com.itheima.c_spring_aop.*.*(..)) ??????????? 選擇方法???????? 返回值任意?? 包???????????? 類名任意?? 方法名任意?? 參數任意 ??????? ??? --> ??? <aop:config proxy-target-class="true"> ??????? <aop:pointcut expression="execution(* com.itheima.c_spring_aop.*.*(..))" id="myPointCut"/> ??????? <aop:advisor advice-ref="myAspectId" pointcut-ref="myPointCut"/> ??? </aop:config> </beans> |
?
2.5.2?? 測試
??? @Test ??? public void demo01(){ ??????? String xmlPath = "com/itheima/c_spring_aop/beans.xml"; ??????? ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); ??????? ??????? //獲得目標類 ??????? UserService userService = (UserService) applicationContext.getBean("userServiceId"); ??????? userService.addUser(); ??????? userService.updateUser(); ??????? userService.deleteUser(); ??? } |
?
3?????? AspectJ
3.1?? 介紹
l? AspectJ是一個基于Java語言的AOP框架
l? Spring2.0以后新增了對AspectJ切點表達式支持
l? @AspectJ 是AspectJ1.5新增功能,通過JDK5注解技術,允許直接在Bean類中定義切面
新版本Spring框架,建議使用AspectJ方式來開發AOP
l? 主要用途:自定義開發
?
3.2?? 切入點表達式【掌握】
1.execution()? 用于描述方法 【掌握】
?????? 語法:execution(修飾符? 返回值? 包.類.方法名(參數) throws異常)
????????????? 修飾符,一般省略
???????????????????? public??????????? 公共方法
???????????????????? *?????????????????? 任意
????????????? 返回值,不能省略
???????????????????? void?????????????? 返回沒有值
???????????????????? String??????????? 返回值字符串
???????????????????? * ????????????????? 任意
????????????? 包,[省略]
???????????????????? com.itheima.crm????????????????? 固定包
???????????????????? com.itheima.crm.*.service???? crm包下面子包任意 (例如:com.itheima.crm.staff.service)
???????????????????? com.itheima.crm..??????????????? crm包下面的所有子包(含自己)
???????????????????? com.itheima.crm.*.service..?? crm包下面任意子包,固定目錄service,service目錄任意包
????????????? 類,[省略]
???????????????????? UserServiceImpl????????????????? 指定類
???????????????????? *Impl????????????????????????????????? 以Impl結尾
???????????????????? User*????????????????????????????????? 以User開頭
???????????????????? *??????????????????????????????????????? 任意
????????????? 方法名,不能省略
???????????????????? addUser????????? ???????????????????? 固定方法
???????????????????? add*?????????????????????????????????? 以add開頭
???????????????????? *Do??????????????????????????????????? 以Do結尾
???????????????????? *??????????????????????????????????????? 任意
????????????? (參數)
???????????????????? ()??????????????????????????????????????? 無參
???????????????????? (int)??????????????????????????????????? 一個整型
???????????????????? (int ,int)????????????????????????????? 兩個
???????????????????? (..)????????????????????????????????????? 參數任意
????????????? throws ,可省略,一般不寫。
?
綜合1
?????? execution(* com.itheima.crm.*.service..*.*(..))
綜合2
?????? <aop:pointcut expression="execution(* com.itheima.*WithCommit.*(..)) ||
???????????????????????? ?execution(* com.itheima.*Service.*(..))" id="myPointCut"/>
2.within:匹配包或子包中的方法(了解)
?????? within(com.itheima.aop..*)
3.this:匹配實現接口的代理對象中的方法(了解)
?????? this(com.itheima.aop.user.UserDAO)
4.target:匹配實現接口的目標對象中的方法(了解)
?????? target(com.itheima.aop.user.UserDAO)
5.args:匹配參數格式符合標準的方法(了解)
?????? args(int,int)
6.bean(id)? 對指定的bean所有的方法(了解)
?????? bean('userServiceId')
?
3.3?? AspectJ 通知類型
l? aop聯盟定義通知類型,具有特性接口,必須實現,從而確定方法名稱。
l? aspectj 通知類型,只定義類型名稱。已經方法格式。
l? 個數:6種,知道5種,掌握1中。
?????? before:前置通知(應用:各種校驗)
????????????? 在方法執行前執行,如果通知拋出異常,阻止方法運行
?????? afterReturning:后置通知(應用:常規數據處理)
????????????? 方法正常返回后執行,如果方法中拋出異常,通知無法執行
????????????? 必須在方法執行后才執行,所以可以獲得方法的返回值。
?????? around:環繞通知(應用:十分強大,可以做任何事情)
????????????? 方法執行前后分別執行,可以阻止方法的執行
????????????? 必須手動執行目標方法
?????? afterThrowing:拋出異常通知(應用:包裝異常信息)
????????????? 方法拋出異常后執行,如果方法沒有拋出異常,無法執行
?????? after:最終通知(應用:清理現場)
????????????? 方法執行完畢后執行,無論方法中是否出現異常
環繞 ? try{ ???? //前置:before ??? //手動執行目標方法 ??? //后置:afterRetruning } catch(){ ??? //拋出異常 afterThrowing } finally{ ??? //最終 after } |
?
?
?
?
?
?
?
?
?
?
?
?
3.4?? 導入jar包
l? 4個:
?????? aop聯盟規范
?????? spring aop 實現
?????? aspect 規范
?????? spring aspect 實現
?
3.5?? 基于xml
1.目標類:接口 + 實現
2.切面類:編寫多個通知,采用aspectj 通知名稱任意(方法名任意)
3.aop編程,將通知應用到目標類
4.測試
?
3.5.1?? 切面類
/** ?* 切面類,含有多個通知 ?*/ public class MyAspect { ??? ??? public void myBefore(JoinPoint joinPoint){ ??????? System.out.println("前置通知 : " + joinPoint.getSignature().getName()); ??? } ??? ??? public void myAfterReturning(JoinPoint joinPoint,Object ret){ ??????? System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret); ??? } ??? ??? public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ ??????? System.out.println("前"); ??????? //手動執行目標方法 ??????? Object obj = joinPoint.proceed(); ??????? ??????? System.out.println("后"); ??????? return obj; ??? } ??? ??? public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ ??????? System.out.println("拋出異常通知 : " + e.getMessage()); ??? } ??? ??? public void myAfter(JoinPoint joinPoint){ ??????? System.out.println("最終通知"); ??? } ? } |
?
3.5.2?? spring配置
<!-- 1 創建目標類 --> ??? <bean id="userServiceId" class="com.itheima.d_aspect.a_xml.UserServiceImpl"></bean> ??? <!-- 2 創建切面類(通知) --> ??? <bean id="myAspectId" class="com.itheima.d_aspect.a_xml.MyAspect"></bean> ??? <!-- 3 aop編程 ??????? <aop:aspect> 將切面類 聲明“切面”,從而獲得通知(方法) ??????????? ref 切面類引用 ??????? <aop:pointcut> 聲明一個切入點,所有的通知都可以使用。 ??????????? expression 切入點表達式 ??????????? id 名稱,用于其它通知引用 ??? --> ??? <aop:config> ??????? <aop:aspect ref="myAspectId"> ??????????? <aop:pointcut expression="execution(* com.itheima.d_aspect.a_xml.UserServiceImpl.*(..))" id="myPointCut"/> ??????????? ??????????? <!-- 3.1 前置通知 ??????????????? <aop:before method="" pointcut="" pointcut-ref=""/> ??????????????????? method : 通知,及方法名 ??????????????????? pointcut :切入點表達式,此表達式只能當前通知使用。 ??????????????????? pointcut-ref : 切入點引用,可以與其他通知共享切入點。 ??????????????? 通知方法格式:public void myBefore(JoinPoint joinPoint){ ??????? ??????????? 參數1:org.aspectj.lang.JoinPoint? 用于描述連接點(目標方法),獲得目標方法名等 ??????????????? 例如: ??????????? <aop:before method="myBefore" pointcut-ref="myPointCut"/> ??????????? --> ??????????? ??????????? <!-- 3.2后置通知? ,目標方法后執行,獲得返回值 ??????????????? <aop:after-returning method="" pointcut-ref="" returning=""/> ??????????????????? returning 通知方法第二個參數的名稱 ??????????????? 通知方法格式:public void myAfterReturning(JoinPoint joinPoint,Object ret){ ??????????????????? 參數1:連接點描述 ??????????????????? 參數2:類型Object,參數名 returning="ret" 配置的 ??????????????? 例如: ??????????? <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" /> ??????????? --> ??????????? ??????????? <!-- 3.3 環繞通知 ??????????????? <aop:around method="" pointcut-ref=""/> ??????????????? 通知方法格式:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ ??????????????????? 返回值類型:Object ??????????????????? 方法名:任意 ??????????????????? 參數:org.aspectj.lang.ProceedingJoinPoint ??????????????????? 拋出異常 ??????????????? 執行目標方法:Object obj = joinPoint.proceed(); ??????????????? 例如: ??????????? <aop:around method="myAround" pointcut-ref="myPointCut"/> ??????????? --> ??????????? <!-- 3.4 拋出異常 ??????????????? <aop:after-throwing method="" pointcut-ref="" throwing=""/> ??????????????????? throwing :通知方法的第二個參數名稱 ??????????????? 通知方法格式:public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ ??????????????????? 參數1:連接點描述對象 ??????????????????? 參數2:獲得異常信息,類型Throwable ,參數名由throwing="e" 配置 ??????????????? 例如: ??????????? <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/> ??????????? --> ??????????? <!-- 3.5 最終通知 -->???????? ??????????? <aop:after method="myAfter" pointcut-ref="myPointCut"/> ??????????? ??????????? ??????????? ??????? </aop:aspect> ??? </aop:config> |
?
?
3.6?? 基于注解
3.6.1?? 替換bean
<!-- 1 創建目標類 --> ??? <bean id="userServiceId" class="com.itheima.d_aspect.b_anno.UserServiceImpl"></bean> ??? <!-- 2 創建切面類(通知) --> ??? <bean id="myAspectId" class="com.itheima.d_aspect.b_anno.MyAspect"></bean> |
?
?
l? 注意:掃描
?
<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:aop="http://www.springframework.org/schema/aop" ?????? xsi:schemaLocation="http://www.springframework.org/schema/beans ?????? ????????????????? ???http://www.springframework.org/schema/beans/spring-beans.xsd ?????? ????????????????? ???http://www.springframework.org/schema/aop ?????? ????????????????? ???http://www.springframework.org/schema/aop/spring-aop.xsd ?????? ????????????????? ???http://www.springframework.org/schema/context ?????? ????????????????? ???http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 1.掃描 注解類 --> ??? <context:component-scan base-package="com.itheima.d_aspect.b_anno"></context:component-scan> |
?
3.6.2?? 替換aop
l? 必須進行aspectj 自動代理
<!-- 2.確定 aop注解生效 --> ?? <aop:aspectj-autoproxy></aop:aspectj-autoproxy> |
?
?
l? 聲明切面
?<aop:aspect ref="myAspectId"> |
?
?
?
l? 替換前置通知
<aop:before method="myBefore" pointcut="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))"/> |
?
?? //切入點當前有效 ?? @Before("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))") ?? public void myBefore(JoinPoint joinPoint){ ????? System.out.println("前置通知 : " + joinPoint.getSignature().getName()); ?? } |
?
l? 替換 公共切入點
<aop:pointcut expression="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" id="myPointCut"/> |
?
//聲明公共切入點 ?? @Pointcut("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))") ?? private void myPointCut(){ ?? } |
?
l? 替換后置
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="ret" /> |
?
??? @AfterReturning(value="myPointCut()" ,returning="ret") ??? public void myAfterReturning(JoinPoint joinPoint,Object ret){ ??????? System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret); ??? } |
?
?
?
l? 替換環繞
<aop:around method="myAround" pointcut-ref="myPointCut"/> |
?
@Around(value = "myPointCut()") ??? public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ ??????? System.out.println("前"); ??????? //手動執行目標方法 ??????? Object obj = joinPoint.proceed(); ??????? ??????? System.out.println("后"); ??????? return obj; ??? } |
?
l? 替換拋出異常
<aop:after-throwing method="myAfterThrowing" pointcut="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" throwing="e"/> |
?
@AfterThrowing(value="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" ,throwing="e") ??? public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ ??????? System.out.println("拋出異常通知 : " + e.getMessage()); ??? } |
?
3.6.3?? 切面類
/** ?* 切面類,含有多個通知 ?*/ @Component @Aspect public class MyAspect { ??? ??? //切入點當前有效 //? @Before("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))") ??? public void myBefore(JoinPoint joinPoint){ ??????? System.out.println("前置通知 : " + joinPoint.getSignature().getName()); ??? } ??? ??? //聲明公共切入點 ??? @Pointcut("execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))") ??? private void myPointCut(){ ??? } ??? //? @AfterReturning(value="myPointCut()" ,returning="ret") ??? public void myAfterReturning(JoinPoint joinPoint,Object ret){ ??????? System.out.println("后置通知 : " + joinPoint.getSignature().getName() + " , -->" + ret); ??? } ??? //? @Around(value = "myPointCut()") ??? public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ ??????? System.out.println("前"); ??????? //手動執行目標方法 ??????? Object obj = joinPoint.proceed(); ??????? ??????? System.out.println("后"); ??????? return obj; ??? } ??? //? @AfterThrowing(value="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" ,throwing="e") ??? public void myAfterThrowing(JoinPoint joinPoint,Throwable e){ ??????? System.out.println("拋出異常通知 : " + e.getMessage()); ??? } ??? ??? @After("myPointCut()") ??? public void myAfter(JoinPoint joinPoint){ ??????? System.out.println("最終通知"); ??? } ? } ? |
?
3.6.4?? spring配置
<!-- 1.掃描 注解類 --> ??? <context:component-scan base-package="com.itheima.d_aspect.b_anno"></context:component-scan> ??? ??? <!-- 2.確定 aop注解生效 --> ??? <aop:aspectj-autoproxy></aop:aspectj-autoproxy> |
?
?
3.6.5?? aop注解總結
@Aspect? 聲明切面,修飾切面類,從而獲得 通知。
通知
?????? @Before 前置
?????? @AfterReturning 后置
?????? @Around 環繞
?????? @AfterThrowing 拋出異常
?????? @After 最終
切入點
?????? @PointCut ,修飾方法 private void xxx(){}? 之后通過“方法名”獲得切入點引用
?
?
?
4?????? JdbcTemplate
l? spring 提供用于操作JDBC工具類,類似:DBUtils。
l? 依賴 連接池DataSource (數據源)
?
4.1?? 環境搭建
4.1.1?? 創建表
create database ee19_spring_day02; use ee19_spring_day02; create table t_user( ? id int primary key auto_increment, ? username varchar(50), ? password varchar(32) ); ? insert into t_user(username,password) values('jack','1234'); insert into t_user(username,password) values('rose','5678'); |
?
4.1.2?? 導入jar包
?
?
4.1.3?? javabean
package com.itheima.domain; ? public class User { ?? ?? private Integer id; ?? private String username; ?? private String password; |
?
4.2?? 使用api(了解)
public static void main(String[] args) { ??????? ??????? //1 創建數據源(連接池) dbcp ??????? BasicDataSource dataSource = new BasicDataSource(); ??????? // * 基本4項 ??????? dataSource.setDriverClassName("com.mysql.jdbc.Driver"); ??????? dataSource.setUrl("jdbc:mysql://localhost:3306/ee19_spring_day02"); ??????? dataSource.setUsername("root"); ??????? dataSource.setPassword("1234"); ??????? ??????? ??????? //2? 創建模板 ??????? JdbcTemplate jdbcTemplate = new JdbcTemplate(); ??????? jdbcTemplate.setDataSource(dataSource); ??????? ??????? ??????? //3 通過api操作 ??????? jdbcTemplate.update("insert into t_user(username,password) values(?,?);", "tom","998"); ??????? ??? } |
?
?
4.3?? 配置DBCP
<!-- 創建數據源 --> ??? <bean id="dataSourceId" class="org.apache.commons.dbcp.BasicDataSource"> ??????? <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> ??????? <property name="url" value="jdbc:mysql://localhost:3306/ee19_spring_day02"></property> ??????? <property name="username" value="root"></property> ??????? <property name="password" value="1234"></property> ??? </bean> ??? <!-- 創建模板 ,需要注入數據源--> ??? <bean id="jdbcTemplateId" class="org.springframework.jdbc.core.JdbcTemplate"> ??????? <property name="dataSource" ref="dataSourceId"></property> ??? </bean> ??? ??? <!-- 配置dao --> ??? <bean id="userDaoId" class="com.itheima.c_dbcp.UserDao"> ??????? <property name="jdbcTemplate" ref="jdbcTemplateId"></property> ??? </bean> |
?
4.4?? 配置C3P0
<!-- 創建數據源 c3p0--> ??? <bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource"> ??????? <property name="driverClass" value="com.mysql.jdbc.Driver"></property> ??????? <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day02"></property> ??????? <property name="user" value="root"></property> ??????? <property name="password" value="1234"></property> ??? </bean> |
?
?
?
4.5?? 使用JdbcDaoSupport
4.5.1?? dao層
?
?
4.5.2?? spring配置文件
??? <!-- 配置dao ??????? * dao 繼承 JdbcDaoSupport,之后只需要注入數據源,底層將自動創建模板 ??? --> ??? <bean id="userDaoId" class="com.itheima.e_jdbcdaosupport.UserDao"> ??????? <property name="dataSource" ref="dataSourceId"></property> ??? </bean> |
?
4.5.3?? 源碼分析
?
4.6?? 配置properties
4.6.1?? properties文件
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql://localhost:3306/ee19_spring_day02 jdbc.user=root jdbc.password=1234 |
?
4.6.2?? spring配置
<!-- 加載配置文件 ????? "classpath:"前綴表示 src下 ????? 在配置文件之后通過? ${key} 獲得內容 ?? --> ?? <context:property-placeholder location="classpath:com/itheima/f_properties/jdbcInfo.properties"/> ?? ?? <!-- 創建數據源 c3p0--> ?? <bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource"> ????? <property name="driverClass" value="${jdbc.driverClass}"></property> ????? <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> ????? <property name="user" value="${jdbc.user}"></property> ????? <property name="password"? value="${jdbc.password}"></property> ?? </bean> |
?
?
?
?
?
5?????? 要求
?
?
?
?????? properties +? JdbcDaoSupport? + c3p0
?????? UserDao? --> api ( update / query? / queryForObject)
?