Java - 框架之 Spring

一. IOC 和 DI

IOC : 控制反转,将对象的创建权反转给了 Spring。
DI  : 依赖注入,前提是必须要有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入(设置)进来。


二. 工厂类

//  1. 加载类路径
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();

// 2. 加载磁盘中的 文件路径
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:/Users/Administrator/Desktop/applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();




三. Bean 的作用范围配置 (xml 文件中)

1. scope : Bean 的作用范围。
!    - singleton     : 默认,Spring 会采用单例模式创建这个对象。
!    - prototype     : 多例模式。(Struts2 和 Spring 整合时会用到)
    - request       : 应用在 Web 项目中,Spring 创建这个类以后,将这个类存入到 request 范围中。
    - session       : 应用在 Web 项目中,Spring 创建这个类以后,将这个类存入到 session 范围中。
    - globalsession : 应用在 Web 项目中,必须在 porlet 环境下使用,如果没有这个环境,相对于 session。



四. Spring 的属性注入方式(xml)

1. 构造方法
// 构造方法 (需要提供构造器)

<!--  1. 构造方法  -->
<bean id="shop" class="com.q.spring.demo2.ShopDao">
    <constructor-arg name="name" value="apple" />
    <constructor-arg name="price" value="100" />
</bean>
@Test
public void demo1(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    ShopDao shopDao = (ShopDao) applicationContext.getBean("shop");
    System.out.println(shopDao);

}



2. set 方式的属性注入

<!--  2. set 方法  -->
<bean id="shop2" class="com.q.spring.demo2.ShopDao2">
    <property name="name" value="pear" />
    <property name="price" value="22" />
</bean>

<!--  2. set 方法 (p名称空间属性注入) -->
<bean id="shop2" class="com.q.spring.demo2.ShopDao2" p:name="q" p:price="2222"></bean>


<!--  2. set 方法 (SpEL 属性注入) -->
<bean id="shop2" class="com.q.spring.demo2.ShopDao2">
    <property name="name" value="#{'q1'}"></property>
    <property name="price" value="#{111}"></property>
</bean>
// set 方式的属性注入(需要提供 set 方法)
@Test
public void demo2(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    ShopDao2 shopDao = (ShopDao2) applicationContext.getBean("shop2");
    System.out.println(shopDao);

}



3. set 方法注入对象类型 (属性中依赖类)

<!--  3. set 方法注入对象类型的属性  -->
<bean id="person" class="com.q.spring.demo2.Person">
    <property name="name" value="q" />
    <property name="shopDao2" ref="shop2" />
</bean>


<!--  3. set 方法注入对象类型的属性 (p名称空间属性注入) -->
<bean id="person" class="com.q.spring.demo2.Person" p:name="q1" p:shopDao2-ref="shop2"></bean>


<!--  3. set 方法注入对象类型的属性 (SpEL 属性注入) -->
<bean id="person" class="com.q.spring.demo2.Person">
    <property name="name" value="#{'q1'}"></property>
    <property name="shopDao2" value="#{shop2}"></property>
</bean>
// set 方法注入对象类型(需要提供 set 方法)
@Test
public void demo3(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    Person person = (Person) applicationContext.getBean("person");
    System.out.println(person);

}




4. p名称空间属性注入

<bean id="person" class="com.q.spring.demo2.Person" p:name="q1" p:shopDao2-ref="shop2"></bean>



5. SpEL 属性注入 (Spring 3.0 之后)

<bean id="shop2" class="com.q.spring.demo2.ShopDao2">
    <property name="name" value="#{'q1'}"></property>
    <property name="price" value="#{111}"></property>
</bean>




6. 集合类型的注入 ( arrs list set map )

private String[] arrs;
private List<String> list;
private Set<String> set;
private Map<String, String> map;
<bean id="typealls" class="com.q.spring.demo2.typeAlls">
    <!--  数组类型  -->
    <property name="arrs">
        <list>
            <value>a</value>
            <value>b</value>
            <value>c</value>
        </list>
    </property>

    <!--  list集合  -->
    <property name="list">
        <list>
            <value>a1</value>
            <value>b1</value>
            <value>c1</value>
        </list>
    </property>

    <!--  set集合  -->
    <property name="set">
        <set>
            <value>a1</value>
            <value>b1</value>
            <value>c1</value>
        </set>
    </property>

    <!--  map 集合  -->
    <property name="map">
        <map>
            <entry key="b2" value="b2" />
            <entry key="b2" value="b2" />
            <entry key="b2" value="b2" />
        </map>
    </property>

</bean>




五. 分模块开发的配置

1. 直接在一个xml文件中导入

<import resource="applicationContext.xml" />   


2. 在创建 ClassPathXmlApplicationContext 时可传多个参数路径

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml1","applicationContext.xml2");



六. Spring 的 IOC 注解开发

1. 引入约束: 使用注解开发引入 Context 约束

<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" 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">
</beans>



2. 开启 Spring 的组件扫描

<!--  配置组件扫描(哪些包下的类使用IOC注解)  -->
<context:component-scan base-package="包路径"></context:component-scan>



3. 在类上添加注解

- @Component : 组件
    - 装饰一个类,将这个类交给 Spring 管理。    

    - 这个注解有三个衍生注解:        - @Controller : web 层
        - @Service       : service 层
        - @Repository : dao 层

import org.springframework.stereotype.Component;

// value 可省略: @Component("shopDao")
@Component(value = "userDao")  // 相当于在 <bean id="userDao" class="com.q.spring.demo2.userDemo2" />
public class userDemo2 implements UserDao {
    public void save(){
        
    }
}


4. 注解方式设置属性值

注解方式:使用注解方式,可以没有 set 方法。

    - 属性如果有 set 方法,需要将属性注入的注解加到 set 方法上。

// 如:
@Value("添加注解")
public void setName(String name){
    this.name = name;
}


   - 属性如果没有 set 方法,需要将属性注入的注解添加到属性上。

// 如:
@Value("添加注解")
private String name;




5. 属性注入的注解

# 普通属性:
    @Value     : 设置普通属性的值
# 对象类型属性:
    @Autowired : 设置对象类型的属性值。但是按照类型完成属性注入(按照类名的一致)。
        - 可以通过 @Qualifier 和 @Autowired 配合使用来修改为按照名称属性注入。
        
    @Resource  : 完成对象类型的属性注入,按照名称完成属性注入。 (常用)。



6. Bean 的其他注解

# 生命周期相关注解:
    @PostConstruct   : 初始化方法
    @PreDestroy         : 销毁方法

# Bean 作用范围的注解:
    @scope    : 作用范围
    参数:
        - singleton : 默认单例
        - prototype : 多例




七. Spring 的 AOP 的 XML 开发
 
1. applocationContext.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: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">

    <!--  配置目标对象 :被增强的对象 -->
    <bean id="productDao" class="com.q.spring.demo1.ProductDaoImpl" />

    <!--  将切面类交给 Spring 管理  -->
    <bean id="myAspect" class="com.q.spring.demo1.MyAspectXml" />

    <aop:config>
        <!--  通过AOP的配置完成对目标类产生代理  -->
        <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.save(..))" id="pointcut1" />
        <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.delete(..))" id="pointcut2" />
        <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.update(..))" id="pointcut3" />
        <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.find(..))" id="pointcut4" />

        <!--  配置切面  -->
        <aop:aspect ref="myAspect">
            <!--  前置通知:获得切入点信息  -->
            <aop:before method="checkPri" pointcut-ref="pointcut1" />
            
            <!--  后置通知  -->
            <aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result" />

            <!--  环绕通知  -->
            <aop:around method="around" pointcut-ref="pointcut3" />

            <!--  异常抛出通知  -->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex" />

            <!--  最终通知  -->
            <aop:after method="after" pointcut-ref="pointcut4" />
        </aop:aspect>
    </aop:config>
</beans>

 

2. ProductDao.java  接口文件

package com.q.spring.demo1;

public interface ProductDao {
    public void save();
    public void update();
    public String delete();
    public void find();
}



3. ProductDaoImpl.java  DAO文件

package com.q.spring.demo1;

public class ProductDaoImpl implements ProductDao {

    @Override
    public void save() {
        System.out.println("save");
    }

    @Override
    public void update() {
        System.out.println("update");
    }

    @Override
    public String delete() {
        System.out.println("delete");
        return "Delete!!!";
    }

    @Override
    public void find() {
        System.out.println("find");
//        int i = 1/0;
    }
}

 

4. MyAspectXML.java

package com.q.spring.demo1;

// 切面类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectXml {

    // 前置通知
    public void checkPri(JoinPoint joinpoint){
        System.out.println("权限校验 "+ joinpoint);
    }

    // 后置通知
    public void writeLog(Object result){
        System.out.println("日志记录 "+ result);
    }

    // 环绕通知 : 性能监控
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("环绕前通知...");
        Object obj = joinPoint.proceed();
        System.out.println("环绕后通知...");
        return obj;
    }

    // 异常抛出通知
    public void afterThrowing(Throwable ex){
        System.out.println("异常抛出通知..."+ ex.getMessage());
    }

    // 最终通知:类似于 finally
    public void after(){
        System.out.println("最终通知...");
    }
}



5. 测试文件

package com.q.spring.demo1;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {

    @Resource(name="productDao")
    private ProductDao productDao;

    @Test
    public void demo1(){
        productDao.save();
        productDao.update();
        productDao.delete();
        productDao.find();
    }
}



八. Srping 的 AOP 注解

1. applocationContext.xml 文件

<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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

        <!--  在配置文件中开启注解的AOP开发  -->
        <aop:aspectj-autoproxy />

        <!--  配置目标类  -->
        <bean id="orderDao" class="com.q.spring.demo1.OrderDao" />

        <!--  配置切面类  -->
        <bean id="myAspect" class="com.q.spring.demo1.MyAspectAnno" />
</beans>


2. OrderDao.java 文件

package com.q.spring.demo1;

public class OrderDao {
    public void save(){
        System.out.println("save...");
    }

    public void update(){
        System.out.println("update...");
    }

    public String delete(){
        System.out.println("delete...");
        return "Delete!!!";
    }

    public void find(){
        System.out.println("find...");
//        int i = 1/0;
    }
}




3. MyAspectAnno.java 文件

package com.q.spring.demo1;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class MyAspectAnno {

    // 前置通知
    // execution(* com.q.spring.demo1.OrderDao.save(..))
    @Before(value = "MyAspectAnno.pointcut1()")
    public void befor(){
        System.out.println("前置增强");
    }

    // 后置通知
    @AfterReturning(value = "MyAspectAnno.pointcut3()", returning = "result")
    public void afterReturning(Object result){
        System.out.println("后置增强 "+ result);
    }


    // 环绕通知
    @Around(value = "MyAspectAnno.pointcut2()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("环绕前增强");
        Object obj = joinPoint.proceed();
        System.out.println("环绕后增强");
        return obj;
    }


    // 异常抛出通知
    @AfterThrowing(value = "MyAspectAnno.pointcut4()", throwing = "e")
    public void afterThrowing(Throwable e){
        System.out.println("异常抛出增强: "+e);
    }


    // 最终通知
    @After(value = "MyAspectAnno.pointcut4()")
    public void afterThrowing(){
        System.out.println("最终增强");
    }

    // 切入点注解
    @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.save(..))")
    private void pointcut1(){}
    @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.update(..))")
    private void pointcut2(){}
    @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.delete(..))")
    private void pointcut3(){}
    @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.find(..))")
    private void pointcut4(){}
}

 

4. SpringDemo1.java 文件

package com.q.spring.demo1;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {

    @Resource(name = "orderDao")
    private OrderDao orderDao;

    @Test
    public void demo1(){
        orderDao.save();
        orderDao.update();
        orderDao.delete();
        orderDao.find();
    }

}

猜你喜欢

转载自www.cnblogs.com/chaoqi/p/10708500.html
今日推荐