Spring-构造注入&注解注入&代理模式&AOP

1.   课程介绍

  • 1.  依赖注入;(掌握)
  • 2.  XML自动注入;(掌握)
  • 3.  全注解配置;(掌握)
  • 4.  代理模式;(掌握)
  • 5.  AOP;(掌握)
  1. 依赖注入;(掌握)

2.1.  构造参数注入java

本身用得很少,除非是其余框架提供的类可能会用到mysql

经常使用的是方案1、二spring

2.1.1.   方案一:根据构造器参数的顺序(索引)sql

<!-- 按照索引注入,索引开始为0 -->编程

<bean id="MyBean" class="cn.itsource._01_.MyBean">数组

         <constructor-arg index="0" value="666" />框架

         <constructor-arg index="1" value="张二娃" />学习

</bean>测试

2.1.2.   方案二:根据构造器参数的名称prototype

<!-- 按照名称注入,名称必须一致,相似set注入相似 -->

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg name="id" value="1" />

         <constructor-arg name="name" value="张三娃" />

</bean>

2.1.3.   方案三:根据构造器的类型注入

<!-- 按照类型注入,必须一一对应,不能有重复的类型-->

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg type="java.lang.Long" value="1" />

         <constructor-arg type="java.lang.String" value="张四娃" />

</bean>

2.2.  若是有一个参数是咱们本身的一个对象,怎么解决?

2.2.1.   方案一:先在外面定义好

<bean id="otherBean" class="cn.itsource._01_.OtherBean"/>

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg  value="1" />

         <constructor-arg  value="张五娃" />

         <constructor-arg ref="otherBean"/>

</bean>

2.2.2.   方案二: 使用一个内部的Bean完成(不须要加id)

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg  value="1" />

         <constructor-arg  value="张六娃" />

         <constructor-arg>

                  <bean class="cn.itsource._01_.OtherBean"/>

         </constructor-arg>

</bean>

2.3.  其它简单、集合属性注入

2.3.1.   准备好相应的类属性

// 简单属性

private Long id;

private String name;

private Boolean sex;

private BigDecimal salary;

 

// 对象属性

private List<OtherBean> otherBeanList;

private Set<String> set;

private Set<OtherBean> otherBeanSet;

private Map<String,Object> map;

 

//下面这个是重点

private Properties props1;

private Properties props2;

private String[] arrays;

private List<String> list;

 

下面的都看一下,大概了解一下就好了

2.4.  数组(两种方案-掌握):

2.4.1.   简写

<property name="arrays" value="A,B,C" />

2.4.2.   完整写法

<property name="arrays">

         <array>

                  <value>xxx</value>

                  <value>yyy</value>

                  <value>zzz</value>

         </array>

</property>

2.5.  List<String>(了解)

<property name="list">

         <list>

                  <value>xxx</value>

                  <value>aaa</value>

                  <value>bbbb</value>

         </list>

</property>

2.6.  Set<String>(了解)

<property name="set">

         <set>

                  <value>xxx</value>

                  <value>aaa</value>

                  <value>bbbb</value>

         </set>

</property>

2.7.  List<OtherBean>(了解)

<property name="otherBeanList">

         <list>

                  <bean class="cn.itsource._01_.OtherBean" />

                  <bean class="cn.itsource._01_.OtherBean" />

                  <ref bean="otherBean" />

                  <ref bean="otherBean" />

         </list>

</property>

2.8.  Set<OtherBean>(了解)

<property name="otherBeanSet">

         <set>

                  <bean class="cn.itsource._01_.OtherBean" />

                  <bean class="cn.itsource._01_.OtherBean" />

                  <ref bean="otherBean" />

                  <ref bean="otherBean" />

         </set>

</property>

2.9.  Map(了解)

<property name="map">

         <map>

                  <entry key="xx" value="value1"></entry>

                  <entry key="yy" value="value2"></entry>

         </map>

</property>

2.10.         这里是我们的重点部分,怎么配置一个Properties对象:

2.10.1.        方案一:简单,不支持中文

<property name="props1">

         <value>

                  Jpa.dialect=org.Jpa.dialect.HSQLDialect

                  Jpa.driverClassName=com.mysql.jdbc.Driver

         </value>

</property>

2.10.2.        方案二:支持中文

<property name="props2">

         <props>

                  <prop key="Jpa.dialect">org.Jpa.dialect.HSQLDialect</prop>

                  <prop key="Jpa.driverClassName">com.mysql.jdbc.Driver中文 </prop>

         </props>

</property>

  1. XML自动注入

使用XML自动注入,能够简化咱们XML的配置。

不过对于学习阶段,并不建议你们这样来使用。

3.1.  简化spring的配置文件

3.1.1.   byName  按照属性的名称  setXxx方法  

         bean.id的名称

3.1.2.   byType   按照注入对象的类型,要求:类型只能配置一个实例

           setXxx方法   注入类的类型(Class)

           和配置文件里面的类型进行比较

           配置文件里面的类型只能是1个

3.2.  配置方案

根节点beans   default-autowire="byName" 对当前配置文件的全部bean都生效

子节点bean autowire="byType"只对当前bean生效

  1. 全注解配置

在Java中写Xml配置Bean仍是比较麻烦,所以,Spring还提供了使用注解来配置的文件。咱们能够来看一下,注解是怎么来配置这个Xml的

配置使用注解流程步骤

4.1.  配置context命名空间

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"

         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.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd">

4.2.  第一步:配置让Spring扫描类与支持注解

<!--

         @Component  普通仓库

         @Repository  仓库(其实就是dao层)

         @Service   service层

         @Controller  控制层(servlet、admin)

 -->

<!-- 进行包的扫描,去看类上面是否有相应的标签配置 -->

<context:component-scan base-package="cn.itsource._03_anno" />

<!-- 这个不是必须的(spring3.2版本前使用) 配上后兼容性好 -->

<context:annotation-config />

4.3.  第二步:在类里面加上注解

4.3.1.   Dao

@Repository

public class UserDao {

         public void save(){

                  System.out.println("保存数据xxxx....");

         }

}

4.3.2.   Service

@Service

public class UserService {

         @Autowired

         private UserDao userDao;

         public void save(){

                  userDao.save();

         }

}

4.3.3.   Action

@Controller

@Scope(“prototype”) 多例

public class UserAction {

         @Autowired

         private UserService userService;

         public String save(){

                  userService.save();

                  return "success";

         }

}

 

4.4.  注解配置bean的名称

4.4.1.   接口有两个实现(可能性比较少)

完成以后,你们注意,如今的配置还有一个问题,好比说我按真实状况来一个Dao接口,而后这个接口有两个实现,如今就会出问题

IUserDao  (UserJdbcDaoImpl/UserJpaDaoImpl)

而咱们声明的时候就是使用了IUserDao

@Service

public class UserService {

         @Autowired

         private IUserDao userDao;

         public void save(){

                  userDao.save();

         }

}

此时会就出错:由于Spring不知道你用的是哪个dao的实现

4.4.2.   解决的方案:为dao生成的bean加上名称,咱们在调用的时候肯定名称便可。

@Repository("userJdbcDao")

public class UserJdbcDaoImpl  implements IUserDao{

         public void save(){

                  System.out.println("保存数据xxxx....");

         }

}

@Repository("userJpaDao")

public class UserJpaDaoImpl  implements IUserDao{

         public void save(){

                  System.out.println("保存数据xxxx....");

         }

}

4.5.  调用名称两套方案:

4.5.1.   方案一:使用@Autowired

@Service

public class UserService {

         @Autowired

         @Qualifier("userJdbcDao")

         private IUserDao userDao;

         public void save(){

                  userDao.save();

         }

}

 

4.5.2.   方案二:使用@Resource

@Service

public class UserService {

         @Resource(name="userJpaDao")

         private IUserDao userDao;

         public void save(){

                  userDao.save();

         }

}

 

4.6.  问题:使用哪种注解来解决比较好?

若是你用的是Spring的注解,尽可能所有使用Spring的注解标签

 

  1. 使用xml版手动注入,xml自动注入仍是注解版?

初学使用xml版,手动注入

熟练以后可使用xml自动注入

之后趋势:注解版

若是是注解版,就所有使用注解(本身写的类),不要混用,其它框架已经写好的类仍然使用xml进行配置

若是是xml版,在测试的使用必须使用注解注入(由于测试框架使用注解版)

 

只有本身写的类,才能够所有用注解,别人写的类使用注解必须去修改别人的源码,添加相应的注解标志(不建议这样搞)

  1. 代理模式

Aop利用代理模式实现功能加强

Aop可以作什么?日志管理,事务管理,权限控制

6.1.  定义

代理模式的英文叫作Proxy或Surrogate,中文均可译为”代理“,所谓代理,就是一我的或者一个机构表明另外一我的或者另外一个机构采起行动。在一些状况下,一个客户不想或者不可以直接引用一个对象,而代理对象能够在客户端和目标对象之间起到中介的做用

6.2.  三种角色

6.2.1.   抽象主题角色:

声明了真实主题和代理主题的共同接口,这样一来在任何可使用真实主题的地方均可以是使用代理主题

6.2.2.   代理主题(Proxy)角色:

代理主题角色内部含有对真实主题的引用,从而能够在任什么时候候操做真实主题对象;

代理主题角色提供一个与真实主题角色相同的接口,以即可以在任什么时候候均可以替代真实主题控制对真实主题的引用,负责在须要的时候建立真实主题对象(和删除真实主题对象);

代理角色一般在将客户端调用传递给真实的主题以前或以后(前置加强/通知,后置加强/通知),都要执行某个操做,而不是单纯地将调用传递给真实主题对象。

6.2.3.   真实主题角色:

定义了代理角色所表明地真实对象

 

 

6.3.  代理模式分类

静态代理/动态代理

6.4.  静态代理

6.4.1.   抽象主题角色

 

6.4.2.   真实主题角色

 

6.4.3.   代理主题角色:中介

代理主题角色内部含有对真实主题的引用

 

6.4.4.   调用方

 

若是有代理主题角色存在,必须修改调用方才能实现代理

 

 

6.4.5.   静态代理的小结

若是有n个接口,必然有n个实现,n个代理类:代码很是多

6.5.  jdk动态代理

和静态代理有相同的抽象主题角色,真实主题角色

JDK动态代理要求它代理的这个真实对象必需要实现某一个接口    

CGLIB 动态代理,真实对象能够不实现接口

Spring中使用代理,若是这个类有接口,默认使用JDK的动态代理,若是这个类没有接口,会使用CGLIB的动态代理

6.5.1.   代理主题角色

 

 

 

6.5.2.   调用方

 

 

6.5.3.   jdk动态代理小结

若是有n个接口,必然有n个实现,只用写1个代理类JDKProxy就能够对全部有接口进行处理

若是有代理主题角色存在,必须修改调用方才能实现代理

6.6.  Cglib动态代理

Cglib相似于javassist-3.18.1-GA.jar功能字节码加强,

原来Hibernate3.2以前就是使用cglib来进行字节码加强

 

6.6.1.   代理主题角色

import org.springframework.cglib.proxy.Enhancer;

import org.springframework.cglib.proxy.MethodInterceptor;

import org.springframework.cglib.proxy.MethodProxy;

 

 

 

 

6.6.2.   cglib动态代理小结

只用写1个代理类CglibProxy就能够对全部没有接口的而且不能是final类都进行处理

若是有代理主题角色存在,必须修改调用方才能实现代理

  1. Spring的AOP

7.1.  早期aop都是spring本身实现,后来仍是用的标准aspects

AOP:面向切面编程

配置的三个元素(什么时候,何地,执行什么功能)

   什么时候:在执行方法以前/以后/有异常...                        前置仍是后置,异常

   何地:在哪个包中的哪个类的哪个方法上面执行            切入点:哪一个包哪一个类哪一个方法

   作什么事: 在UserServie中执行update方法以前添加日志   加强/通知

7.2.  Spring有两种代理方案:

7.2.1.   若目标对象实现了若干接口

spring使用JDK的java.lang.reflect.Proxy类代理。

7.2.2.   若目标对象没有实现任何接口,

spring使用CGLIB库生成目标对象的子类。

7.2.3.   使用该方案时须要注意:

 1.对接口建立代理优于对类建立代理,由于会产生更加松耦合的系统。

     对类代理是让遗留系统或没法实现接口的第三方类库一样能够获得通知,

            这种方案应该是备用方案。

 2.标记为final的方法不可以被通知。spring是为目标类产生子类。任何须要

             被通知的方法都被复写,将通知织入。final方法是不容许重写的。

7.3.  Xml版

7.3.1.   添加jar文件

aspects

spring-framework-4.1.2.RELEASE-dependencies\org.aopalliance\com.springsource.org.aopalliance\1.0.0\com.springsource.org.aopalliance-1.0.0.jar

 

 

spring-framework-4.1.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE\com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

7.3.2.   添加aop命名空间

xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

7.3.3.   前置加强(通知)

 

7.3.4.   后置加强,异常加强,最终加强

 

7.3.5.   环绕加强(前面的4个加强就不用了)

 

7.3.6.   环绕方法

import org.aspectj.lang.ProceedingJoinPoint;

 

 

7.4.  注解版

7.4.1.   配置文件

 

7.4.2.   事务管理器

 

 

 

7.4.3.   AOP中的概念

什么叫作AOP:Aspect oritention programming(面向切面编程)

 

AOP当中的概念:

1,切入点Pointcut:在哪些类,哪些方法上面切(where);

2,加强,通知Advice(对应到一个方法):在方法的什么时机(when)作什么(what);

3,切面Aspect:切入点+通知

4,织入Weaving:把切面加入到对象,并建立出代理对象的过程.

相关文章
相关标签/搜索