Spring如何配置Bean以及配置AOP

目录

如何创建一个基础的Spring工程?

配置bean的注入方式:

bean配置的继承

使用bean的scope属性来配置bean的作用域

IOC容器中Bean的生命周期方法

配置AOP

使用注解进行增强配置:


如何创建一个基础的Spring工程?

1、先建立一个java工程

2、导入Spring所依赖的基础包:

  • spring-aop-3.2.13.RELEASE.jar
  • spring-beans-3.2.13.RELEASE.jar
  • spring-context-3.2.13.RELEASE.jar
  • spring-core-3.2.13.RELEASE.jar

3、创建xml文件(文件名:applicationContext.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       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-3.2.xsd
	   http://www.springframework.org/schema/context
	   http://www.springframework.org/schema/context/spring-context.xsd
	   http://www.springframework.org/schema/util
	   http://www.springframework.org/schema/util/spring-util.xsd">

</beans>

4、编写POJO

public class HelloWorld {
    private String name;

    public HelloWorld() {
        System.out.println("HelloWorld无参构造器...");
    }

    public HelloWorld(String name) {
        System.out.println("HelloWorld有参构造器...");
        this.name = name;
    }
    public void setName(String name) {
        System.out.println("setName方法...");
        this.name = name;
    }

    public void hello(){
        System.out.println("hello:"+name);
    }

}

5、在配置文件中配置bean

    <!--
        配置bean
        class: bean 的全类名,通过反射的方式在 IOC 容器中创建 bean,所以要求bean中必须有无参数的构造器
        id: 标识容器中的bean,id唯一
    -->
    <bean id="helloWorld" class="com.self.spring.beans.HelloWorld">
    <!--属性注入,通过bean的set方法
        name为属性名,value为属性值-->
        <property name="name" value="Spring11111"/>
    </bean>
    <bean id="helloWorld1" class="com.self.spring.beans.HelloWorld">
    <!--构造器注入,通过bean的构造器
        name为属性名,value为属性值-->
        <constructor-arg name="name" value="Spring22222"/>
    </bean>

6、在java中获取bean对象

        //ApplicationContext :IOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //通过beanId返回IOC容器中的Bean
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld1");
        //通过类型返回IOC容器中的Bean,但要求IOC容器中必须只能有一个该类型的Bean
//        HelloWorld helloWorld1 = ctx.getBean(HelloWorld.class);
        helloWorld.hello();

控制台结果>>

HelloWorld无参构造器...
setName方法...
HelloWorld有参构造器...
hello:Spring22222

配置bean的注入方式:

首先得有一个Car类,在配置文件中来配置bean

public class Car {
    private String brand;
    private String corp;
    private double price;
    private int maxSpeed;

    public Car() {}

    public Car(String brand, String corp, double price) {
        this.brand = brand;
        this.corp = corp;
        this.price = price;
    }

    public Car(String brand, String corp, int maxSpeed) {
        this.brand = brand;
        this.corp = corp;
        this.maxSpeed = maxSpeed;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public void setCorp(String corp) {
        this.corp = corp;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", corp='" + corp + '\'' +
                ", price=" + price +
                ", maxSpeed=" + maxSpeed +
                '}';
    }
}

 注入方式:

  1. 属性注入
  2. 构造器注入
  3. p命名空间注入
    <bean id="car1" class="com.self.spring.beans.Car">
        <!--name为构造器上的参数名,来定位构造器-->
        <constructor-arg name="brand" value="大众"/>
        <constructor-arg name="corp" value="上海"/>
        <constructor-arg name="maxSpeed" value="200"/>
    </bean>
    <bean id="car2" class="com.self.spring.beans.Car">
        <!--可以在type上写上参数类型,来定位重载构造器-->
        <constructor-arg value="奔驰" index="0"/>
        <constructor-arg value="上海" index="1"/>
        <constructor-arg value="500000" type="double"/>
    </bean>
    <bean id="car3" class="com.self.spring.beans.Car">
        <!--构造器与属性联用,用到属性的需要set方法-->
        <constructor-arg name="brand" value="奥迪"/>
        <constructor-arg name="corp" value="上海"/>
        <constructor-arg name="maxSpeed" value="250"/>
        <!--属性注入,通过bean的set方法,name为属性名,value为属性值-->
        <property name="price" value="300000"/>
    </bean>
    <!-- 通过p命名空间来注入,实质是通过set方法来实现 -->
    <bean id="car4" class="com.self.spring.beans.Car" p:brand="宝马" p:corp="德国" p:maxSpeed="250" />

还可以配置单例集合bean,以供多个bean进行引用,需要导入util命名空间

    <util:list id="cars">
        <ref bean="car1"/>
        <ref bean="car2"/>
        <ref bean="car3"/>
        <ref bean="car4"/>
    </util:list>

bean配置的继承

<!--
        bean配置的继承
        parent="父bean的id",子bean也可以覆盖继承后的属性值
        abstract="true" 表示该bean为抽象bean,不能被实例化,用来当作模板。当bean中没有class属性时,abstract必须为true,只能当作模板
        但abstract、autowire等属性不会被继承
    -->
    <bean id="AbstractCar" class="com.self.spring.beans.Car" p:brand="五菱宏光" abstract="true"/>
    <bean id="car5" parent="AbstractCar" p:price="600000"/>

使用bean的scope属性来配置bean的作用域

<!--
        什么是作用域,默认情况下在IOC容器中getbean("beanId")获得的是同一个对象,也就是说是单例的
        可以通过修改scope属性来改变作用域
        scope="singleton" 默认的
        scope="prototype" 在IOC容器中getbean("beanId")时创建一个新的对象
    -->
    <bean id="car6" class="com.self.spring.beans.Car" p:brand="尼桑" p:corp="日本" />
    <bean id="car7" class="com.self.spring.beans.Car" p:brand="BYD" p:corp="中国" scope="prototype"/>

IOC容器中Bean的生命周期方法

<!--
        1、创建Bean,构造器
        2、设置属性或对其他Bean的引用
        3、调用Bean的初始化方法
        4、Bean可以使用了
        5、当容器关闭时调用Bean的销毁方法
    -->
    <!--在Bean的声明里设置init-method和destroy-method属性,为bean指定初始化和销毁方法,是单一的处理-->
    <bean id="car8" class="com.self.spring.beans.Car" init-method="initfun" destroy-method="destroyfun"/>

    <!--创建Bean后置处理器,bean后置处理器允许在调用初始化方法前后对bean进行额外的处理,对每个实例都会处理不是单一的处理-->
    <!--实现BeanPortProcessor 接口,并为下面两方法具体提供方法体
        1、public Object postProcessBeforeInitialization(Object bean, String beanName)在初始化方法前执行
        2、初始化方法()
        3、public Object postProcessAfterInitialization(Object bean, String beanName)在初始化方法后执行
        将bean实例传给bean参数,beanName为IOC的beanId
    -->
    <!--配置bean后置处理器类-->
    <bean class="com.self.spring.MyBeanPostProcessor.MyPostProcessor"/>

在bean中写上初始化方法、销毁方法,方法名应与该属性的值相同 init-method="initfun" destroy-method="destroyfun"

public class Car{

    ......

    public void initfun(){
        System.out.println("Car的初始化方法...");
    }
    public void destroyfun(){
        System.out.println("Car的销毁方法...");
    }
}

创建后置处理器,实现BeanPostProcessor接口

public class MyPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean+","+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean+","+beanName);
        return bean;
    }
}

配置AOP

什么时候会应用到AOP技术呢?在代码需要扩展的时候,AOP技术可以在不修改源码的情况下进行增强处理

有一个这样的代码:

public class OldProcess {

    public int oldProcessfun1(){
        System.out.println("oldProcess程序(版本1.0)执行...");
        //发生异常
        /*int[] a = new int[1];
        a[100] = 9;*/
        return 1;
    }
}

 运行的代码

public static void main(String[] arg){
        OldProcess oldProcess1 = (OldProcess) ctx.getBean("oldProcess1");
        oldProcess1.oldProcessfun1();
}

当需要在 oldProcessfun1() 执行前想增加其他业务代码时,就可以配置前置增强:

1、创建含业务代码的类:

public class BeforeAspect {
    public void beforeAspectfun(JoinPoint jp){
        System.out.println("前置增强程序...");
    }
}

2、在xml文件中进行AOP配置

<!-- AOP配置开始 -->
    <!--切入点所对应的对象,必须在IOC容器中-->
    <bean id="oldProcess1" class="com.self.spring.oldProcess.OldProcess"/>
    <!-- 配置增强处理类的bean -->
    <bean id="beforeAspect1" class="com.self.spring.aspect.BeforeAspect"/>
    <aop:config>
        <!-- 配置切入点
        注意:切入点所对应的对象一定要是IOC容器中的Bean-->
        <aop:pointcut id="pointCut1" expression="execution(public int oldProcessfun1())"/>

        <!-- 配置切面 -->
        <aop:aspect ref="beforeAspect1">
            <!--前置增强,使beforeAspectfun方法在执行切入点方法前执行-->
            <aop:before method="beforeAspectfun" pointcut-ref="pointCut1"/>
        </aop:aspect>
    </aop:config>

另外还有后置增强、最终增强、环绕增强、异常处理增强

xml配置:

    <!-- AOP配置开始 -->

    <!--切入点所对应的对象,必须在IOC容器中-->
    <bean id="oldProcess1" class="com.self.spring.oldProcess.OldProcess"/>

    <!-- 配置增强处理类的bean -->
    <bean id="beforeAspect1" class="com.self.spring.aspect.BeforeAspect"/>
    <bean id="afterAspect1" class="com.self.spring.aspect.AfterAspect"/>
    <bean id="throwAspect1" class="com.self.spring.aspect.ThrowAspect"/>
    <bean id="finallyAspect1" class="com.self.spring.aspect.FinallyAspect"/>
    <bean id="aroundAspect1" class="com.self.spring.aspect.AroundAspect"/>
    <aop:config>
        <!-- 配置切入点
        注意:切入点所对应的对象一定要是IOC容器中的Bean-->
        <aop:pointcut id="pointCut1" expression="execution(public int oldProcessfun1())"/>

        <!-- 配置切面 -->
        <aop:aspect ref="beforeAspect1">
            <!--前置增强,使beforeAspectfun方法在执行切入点方法前执行-->
            <aop:before method="beforeAspectfun" pointcut-ref="pointCut1"/>
        </aop:aspect>
        <aop:aspect ref="afterAspect1">
            <!--
            后置增强,使afterAspectfun方法在执行切入点方法后执行,
            并且afterAspectfun能够获取切入点方法的返回值,
            0oldMethodResult为afterAspectfun方法的参数,用于接收切入点方法的返回值
            -->
            <aop:after-returning method="afterAspectfun" pointcut-ref="pointCut1" returning="oldMethodResult"/>
            <!--注意:后置增强与环绕增强处理联用会使后置增强获取不到oldProcess程序的返回值,因为该返回值在环绕增强中接收了-->
        </aop:aspect>
        <aop:aspect ref="throwAspect1">
            <!--异常处理增强,使throwAspectfun1方法在切入点执行发生错误时执行-->
            <aop:after-throwing method="throwAspectfun1" pointcut-ref="pointCut1" throwing="excep"/>
        </aop:aspect>
        <aop:aspect ref="finallyAspect1" >
            <!--最终增强处理-->
            <aop:after method="finallyAspectfun1" pointcut-ref="pointCut1"/>
        </aop:aspect>
        <aop:aspect ref="aroundAspect1">
            <!--环绕增强处理-->
<!--            <aop:around method="ArroundAspectMethod1" pointcut-ref="pointCut1"/>-->
        </aop:aspect>
    </aop:config>

java代码:

public class AfterAspect {

    public void afterAspectfun(JoinPoint jp,Object oldMethodResult){
        System.out.println("后置增强程序..."+"oldProcess的返回值:"+oldMethodResult);
    }
}

public class FinallyAspect {

    public void finallyAspectfun1(JoinPoint jp){
        System.out.println("最终增强程序...");
    }
}

public class AroundAspect {

    public void ArroundAspectMethod1(ProceedingJoinPoint jp) {

        try {
            System.out.println("环绕处理增强,在oldProcess程序执行前执行...");
            //以上代码相当与前置增强
            Object ret = jp.proceed();//执行oldProcess程序
//以下代码相当与后置增强
            System.out.println("环绕处理增强,在oldProcess程序执行后执行..."+"oldProcess的返回值:"+ret);

        } catch (Throwable throwable) {
            //相当与异常处理增强
            System.out.println("环绕处理增强,在oldProcess程序执行异常时执行...");

            throwable.printStackTrace();
        } finally {
            //相当与最终增强
            System.out.println("环绕处理增强,在oldProcess程序执行无论报不报异常都执行...");
        }
    }
}

public class ThrowAspect {

    public void throwAspectfun1(JoinPoint jp, Exception excep){
        System.out.println("异常发生后执行的代码...");
    }
}

使用注解进行增强配置:

xml文件配置:

    <!--开启AOP注解支持-->
    <aop:aspectj-autoproxy/>
    <!--配置使用注解的类-->
    <bean class="com.self.spring.aspectUseAnnotation.AspectAnnotation"/>
    <!--开启注解所在的包的扫描-->
    <context:component-scan base-package="com.self.spring.aspectUseAnnotation"/>

java代码:

@Aspect
public class AspectAnnotation {

    /**
     * 前置增强
     * @param jp
     */
    @Before("execution(public int oldProcessfun1())")
    public void beforeMethod(JoinPoint jp){
        System.out.println("注解实现前置增强程序...");
    }

    /**
     * 异常处理增强
     * @param jp
     * @param e
     */
    @AfterThrowing(pointcut = "execution(public * oldProcessfun1())",throwing="e")
    public void throwMethod(JoinPoint jp,Exception e){
        System.out.println("注解实现异常处理增强程序...");
    }

    /**
     * 最终增强
     * @param jp
     */
    @After("execution(public * oldProcessfun1())") //相当于配置了切入点、
    public void afterMethod(JoinPoint jp){
        System.out.println("注解实现最终增强程序...");
    }

    /**
     * 后置增强,与环绕增强处理联用会使后置增强获取不到oldProcess程序的返回值,因为该返回值在环绕增强中接收了
     * @param jp
     */
    @AfterReturning(pointcut = "execution(public * oldProcessfun1())",returning = "ret")
    public void afterReturnMethod(JoinPoint jp ,Object ret) {
        System.out.println("注解实现后置增强程序..."+"oldProcess的返回值:"+ret);
    }
    /**
     * 环绕增强
     */
//    @Around("execution(public * oldProcessfun1())")
    public void aroundMethod(ProceedingJoinPoint jp) {
        try {
            System.out.println("注解实现环绕处理增强,在oldProcess程序执行前执行...");
            //以上代码相当与前置增强
            Object ret = jp.proceed();//执行oldProcess程序
//以下代码相当与后置增强
            System.out.println("注解实现环绕处理增强,在oldProcess程序执行后执行..."+"oldProcess的返回值:"+ret);

        } catch (Throwable throwable) {
            //相当与异常处理增强
            System.out.println("注解实现环绕处理增强,在oldProcess程序执行异常时执行...");

            throwable.printStackTrace();
        } finally {
            //相当与最终增强
            System.out.println("注解实现环绕处理增强,在oldProcess程序执行无论报不报异常都执行...");
        }
    }
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP配置可以通过XML方式或注解方式进行。 XML方式配置步骤如下: 1. 在Spring配置文件中引入aop的约束,例如:xmlns:aop="http://www.springframework.org/schema/aop"。 2. 把通知Bean交给Spring管理,使用<bean>标签进行配置。 3. 使用<aop:config>标签开始AOP配置。 4. 使用<aop:aspect>标签配置切面。 5. 使用对应的标签配置通知的类型,例如<aop:before>表示前置通知。 6. 在<aop:before>标签中指定通知方法和切入点表达式。 注解方式配置步骤如下: 1. 在配置类上使用@Configuration注解进行标记。 2. 使用@ComponentScan注解指定需要扫描的包。 3. 使用@EnableAspectJAutoProxy注解开启Spring对注解AOP的支持。 以上是关于Spring AOP配置的简要说明,具体的配置内容可以参考引用的资料\[1\]、\[2\]和\[3\]。 #### 引用[.reference_title] - *1* *3* [Spring AOP 应用:三种配置及实现方式](https://blog.csdn.net/qq_37829947/article/details/117955529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【spring配置】——spring aop配置](https://blog.csdn.net/javawebxy/article/details/50492616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值