Java spring

高内聚,低耦合:
1.优点:
方便解耦,简化开发
AOP编程支持
事务支持
方便程序测试
集成各种框架
降低javaEEAPI的使用难度
2.结构:
Test:整合Junit
Core Container:
Beans 管理bean
Core 核心
Context 上下文,配置文件
Expression Language:SPEL,表达式语言
AOP:切面编程
Aspects:AOP框架
Data Access/Integration
JDBC:JdbcTempla
3.配置文件
位置任意,推荐src下;名字任意,推荐applicationContext
配置文件添加约束:
<beans xmlns="http://www.springframework.org/schema/beans"
       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-3.0.xsd">
4.IOC  控制反转
通过程序创建对象,而不是程序员
5.DI  依赖注入
依赖:一个对象需要使用另一个对象
注入:对另一个对象的数据设置
注入方式:
set
基本类型:
<property name = ""  value = ""> </property>
<property name = "">
 <value>""</value>
 </property>
引用类型:
<property name = ""  ref = ""> </property>
<property name = "">
 <ref bean = ""/>
 </property>
constructor
<constructor-arg name = "" value = ""  index = "">  </constructor-arg> 
p命名空间方式
在第三行添加:xmlns=p:"http://www.springframework.org/schema/p"
对 set方式的简化:
例如:<property name = ""  value = ""> </property>  ------>    bean属性中添加p:name = ""
<property name = ""  ref = ""> </property>   ------> bean属性中添加p:name-ref = ""
spel表达式
对set的简化,值全部由value表示,主要操作
value = #{123},#{'字符串'}:数字和字符串,注意单引号
value = #{name}:表示其他引用
value = #{name?.value}:使用其他引用的值或者方法,?.表示如果对象不为null则调用其方法
value = #{T(java.lang.Math).value}:调用静态方法或者及静态成员
集合注入:
<property name = "">
 <array>
  <value>""</value>
  <value>""</value>
  <value>""</value>
 </array>
</property>
<property name = "">
 <map>
  <entry key = "" value = ""></entry>
  <entry key = "" value = ""></entry>
  <entry key = "" value = ""></entry>
 </map>
</property>
<property name = "">
 <props>
  <prop key = "高富帅">女男女</prop>
  <prop key = "白富美">男女男</prop>
  <prop key = "男屌丝">手上下</prop>
 </props>
</property>
…………………………
基于注解的注入:
@Compnent 代表<bean class = ""></bean>
@compnent("name") 代表<bean name = "name" class = ""></bean>
注解使用前提,使用命名空间,让spring扫描
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
通过<context:component-scan base-pakage = ""></context:component-scan>指定扫描的类
各种注解的意义:
@Compnent 代表<bean class = ""></bean>
@compnent("name") 代表<bean name = "name" class = ""></bean>
web三层的几个注解
@Controller action
@Service  service
@Repository dao
值的注入:
基本类型----->@Value("value")
引用类型----->1.@Autowired 按照类型注入
2.@Autowired @Qualifier("name") 按照名字注入
3.@Resource(name = "name")或@Resource按照名字注入或者类型注入
特殊注解:@PostConstruct   与init-method等效 @PreDestroy  与destroy-method等效   @Scope  设置作用域

6.xml提示,添加约束
找到spring中schema文件位置,在catalog中的user special entries找到上述文件,keytype选择schema name,key为http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7.主要API
BeanFactory:任意Bean的构造工厂,第一次getBean时才会实例化Bean对象
ApplicationContext(容器初始化就会实例化所有bean对象)、ClassPathXmlApplicationContext(类路径xml,src)、FileSystemXmlApplicationContext(加载制定盘符的xml)
8.作用域,scope,生成对象的个数
singleton(单例),prototype(多例)
9.Bean的生命周期
Bean的定义:new Bean()
设置初始化回调:在配置文件中添加init-method = “”并且在Bean中添加相应方法
或者实现InitialingBean接口,实现其afterPropertiesSet()方法
Bean的初始化:init()
Bean的使用:ClassPathXmlApplicationContext
Bean的销毁:destroy()
设置销毁前回调:在配置文件中添加destory-method = “”并且在Bean中添加相应方法
或者实现DisposableBean接口,实现其destroy方法
Bean后处理器:新建一个类实现BeanPostProcessor接口,并覆盖postProcessAfterInitialization方法和postProcessBeforeInitialization方法,然后在applicationContext.xml中配置<bean class = "全限定类名"></bean>
这两个方法分别在init方法前和后调用,可在后处理中设置Bean对象的代理,这样设置后所有bean的init都会被处理
10.AOP  面向切片编程 底层用代理实现 横向抽取
术语介绍
target:目标类,需要增强的类
linkpoint:连接点,目标类的方法
pointcut:切入点,已经增强的方法
advice:增强,自己添加的方法
weaving:连接的过程
aspect:切面,由所有advice与pointcut组成的“面”
代理方式
a:手动代理
--jdk动态代理 目标类必须实现接口
Proxy.newProxyInstance();
--cglib动态代理 需要cglib包和asm包,但是spring的core包中已经集成了这两个包,不需要自己导包;目标类不需要实现接口,利用继承返回子类
Enhancer 类  setSuperClass,setCallBack,create

b:半自动代理 在xml中配置代理对象
需要导入的包:spring-aop,spring-aopaliance
具体配置
   <!-- 创建目标类 -->
   <bean name = "user" class = "com.xiao.bean.Users"></bean>
   <!-- 创建切面类 -->
   <bean name = "userAopAspect" class = "com.xiao.aspect.UsersAopAspect"></bean>
  
   <!-- 创建代理类 -->
   <bean name = "proxyUser" class = "org.springframework.aop.framework.ProxyFactoryBean">
     <property name = "optimize" value = "true"></property>//设置为cglib代理,因为没有实现接口,默认为jdk代理
     <property name="target" ref = "user"></property>
     <property name="interceptorNames" value = "userAopAspect"></property>
   </bean>
通过getBean("proxyUser")可得到代理对象
spring提供的几个通知规范:
前置--MethodBeforeAdvice 抛出异常可以阻止目标方法执行
后置--AfterReturningAdvice 可以获得目标方法的返回值
环绕--MethodInterceptor
异常抛出--ThrowsAdvice
切面类:public class UsersAopAspect implements MethodInterceptor 实现MethodInterceptor接口,代表环绕通知
c:aop全自动代理
---导入命名空间aop
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd
具体配置:
<!-- 创建目标类 -->
   <bean name = "user" class = "com.xiao.bean.Users"></bean>
   <!-- 创建切面类 -->
   <bean name = "userAopAspect" class = "com.xiao.aspect.UsersAopAspect"></bean>
  
   <aop:config>
     <aop:pointcut expression="execution(* com.xiao.bean.Users.*(..))" id="pointCut"/>
     <aop:advisor advice-ref="userAopAspect" pointcut-ref = "pointCut"/>
   </aop:config>
通过getBean("user")获取对象,如果配置了<aop:config>则得到的时代理对象,如果没有配置则得到原本的对象
默认时jdk动态代理,通过配置属性(aop:config的)proxy-target-class = ”true“,可以声明为cglib代理
11.AspectJ表达式
*代表任意
语法:execution(修饰符  返回值  包名 . 类名 . 方法名(参数) throws 异常)
修饰符:一般省略
返回值:不可省略
包名:可省略
类名:可省略
方法名:不可省略
参数:..代表任意参数
异常:一般省略
execution(* com.xiao..*.*(..))

12.AspectJ通知
导包:aopalliance、spring-aop、spring-aspectj、aspectj-weaver
--基于xml,具体配置:
<!-- aspectJ 前置 -->
  
   <!-- 创建目标类 -->
   <bean name = "user" class = "com.xiao.bean.Users"></bean>
   <!-- 创建切面类 -->
   <bean name = "userAspectJ" class = "com.xiao.aspect.UsersAspectJ"></bean>
  
   <aop:config >
     <aop:aspect ref="userAspectJ">
      <aop:pointcut expression="execution(* com.xiao.bean.Users.*(..))" id="usersPointCut"/>
      <aop:before method="myBefore"(切面类中的方法) pointcut-ref="usersPointCut"/>
     </aop:aspect>
   </aop:config>
=================================================================
<!-- aspectJ 后置 -->
 <!-- 创建目标类 -->
 <bean
  name="user"
  class="com.xiao.bean.Users"></bean>
 <!-- 创建切面类 -->
 <bean
  name="userAspectJ"
  class="com.xiao.aspect.UsersAspectJ"></bean>

 <aop:config>
  <aop:pointcut
   expression="execution(* com.xiao.bean.Users.*(..))"
   id="userPointCut" />
  <aop:aspect ref="userAspectJ">
   <aop:after-returning
    method="myAfterReturning"
    pointcut-ref="userPointCut"
    returning="ret" />
  </aop:aspect>
 </aop:config>
切面类的方法中可以添加参数,参数类型必须为Object,并将参数名放入returning中,表示方法的返回值
=====================================================================
<!-- aspectJ 环绕 -->
 <!-- 创建目标类 -->
 <bean
  name="user"
  class="com.xiao.bean.Users"></bean>
 <!-- 创建切面类 -->
 <bean
  name="userAspectJ"
  class="com.xiao.aspect.UsersAspectJ"></bean>

 <aop:config>
  <aop:pointcut
   expression="execution(* com.xiao.bean.Users.*(..))"
   id="userPointCut" />
  <aop:aspect ref="userAspectJ">
   <aop:around
    method="myAround"
    pointcut-ref="userPointCut"
    />
  </aop:aspect>
 </aop:config>
通知方法中的参数类型为ProceedJoinPoint,返回值必须为Object,必须抛出异常,手动调用目标方法
几个通知共有特点
pointcut = “execution()”(只能自己用一次)
pointcut-ref = ""(公用的切入点)
切面类的方法中可以添加参数JoinPoint joinPoint,通过该参数可获得目标类当前执行的方法信息
--基于注解的aop编程
xml的配置:
 <context:component-scan base-package="com.xiao.bean"></context:component-scan>
 <context:component-scan base-package="com.xiao.aspect"></context:component-scan>
 <aop:aspectj-autoproxy ></aop:aspectj-autoproxy>//扫描@Aspect,@Before等注解,必须加
切面类具体方法:
 @Pointcut("execution(* com.xiao.bean.Users.*(..))")//声明共有切入点
 private void publicPointCut(){
  
 }
 
// @Before("execution(* com.xiao.bean.Users.*(..))")//该切入点只能自己用
 public void myBefore(JoinPoint joinPoint) {
  System.out.println("前置" + joinPoint.getSignature().getName());
 }
 
// @AfterReturning(value = "publicPointCut()",returning = "ret")
 public void myAfterReturning(JoinPoint joinPoint,Object ret) {
  System.out.println("后置" + joinPoint.getSignature().getName() + ret);
 }
 
 @Around("publicPointCut()")
 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
  System.out.println("前置");
//  手动执行目标方法
  Object obj = joinPoint.proceed();
  System.out.println("后置");
  return obj;
 }
需注意使用共有切入点时需要方法名加括号,必须要有括号
 
 
 
 
 
 

posted on 2018-11-27 20:11  -Yoda-  阅读(85)  评论(0编辑  收藏  举报

导航