spring基础

spring依赖注入的方式

先引入jar包,才能在spring配置文件中方便的写

 

 

 

可以根据set方式完成属性的注入,在配置文件spring中,<bean></bean>,表示每个类,其中id属性表示为这个类起别名,class表示这个类在工程下的位置,bean标签里面包含property这个标签,里面的name属性代表这个类中的属性名,value表示为这个属性名初始化赋值,如下:

<bean id="app" class="com.zhiyou100.lw.spring.App">
        <property name="name" value="${app.name}"></property>
        <property name="age" value="${app.age}"></property>
        <property name="student" ref="${app.stu}"></property>
</bean>

其中value初始化时我使用了$符,代表我使用了属性文件了,app.什么的我都事先在属性文件中赋值好了的,直接拿到这里来用,这样把值分开了写,是为了能好修改很多代码,现在的代码很少,等到真正开发的时候就很多了,想用里面的数据就好管理了,其中要引入属性文件必须在这个配置文件中添加标签

<context:property-placeholder location="classpath:my.properties"/>    其中的my.property是属性的命名,classpath是路劲,要把属性文件放在和spring配置文件同一个文件夹下,属性文件里的内容

app.name=zhang
app.age=20
app.student=stu

还有就是通过构造方法来注入的,还是用bean标签来得到类,和类名。bean标签有constructor-arg标签 index属性表示构造方法的括号里面的参数从第几个开始的,index值为0代表的是为只有一个参数的构造方法赋值,那么index值为1代表的是为有两个参数的构造方法赋值,如下:

 

 

 依赖注入的数据类型

一种是基本数据类型和字符串,还一种是类类型,就是说在赋值的时候,可以赋的是基本数据类型和字符串,这些都是用value来赋值的,象类类型,就是用ref来赋值的,它的值是某个类用bean标签写在配置文件中的名字,还有可以为LIst集合赋值,Map集合赋值,它们都是在property标签里另调用那两个集合的标签的。

LIst集合数据的注入:

 

 

 Map集合数据的注入:

 

 

 Bean标签的作用域

用Bean标签创建的类对象,默认的作用域是单例模式,其中有scope的属性,它的值有prototype:表示的是原生格式,值为singleton:表示的是单例格式,如下:

 

 

 使用注解方式

一再引入jar包

 

 

 然后再配置文件中进行包扫描:我的代码是<context:component-scan base-package="com.zhiyou100.lw"></context:component-scan>双引号中的内容就是要对那些包啊,类啊,进行操作使用注解的,因为我直接输入的是包的位置,所以此包下的所有子包和子类,都包括在内,然后在相应的类上加上注解,@Repository表示的是持久化的注解,一般用在Dao中,@Service表示业务层注解,一般用在service中,@Controller表示控制层注解,一般用在controller中,还有一个也表示标记该类使用注解的叫@Component组件(),@Autowired表示自动注入,首先按照类型帮你自动注入,如果多个类型相同,自动会按照名称注入的,@Resource 也是自动注入,它是先按照名称注入的,名称相同的话,就会按照类型注入的。

controller的的代码:

@Controller(value="controller")
public class Ucontroller {
    @Resource(name="userservice")
    private Service service;

    public Service getService() {
        return service;
    }

    public void setService(Service service) {
        this.service = service;
    }
    public void fun(int a) {
        service.show(a);
    }
}

service代码:

@org.springframework.stereotype.Service(value="userservice")
public class ServiceImp implements Service{
    @Resource(name="userDao")
    private DaoImp dao;
    

    public DaoImp getDao() {
        return dao;
    }


    public void setDao(DaoImp dao1) {
        dao = dao1;
    }


    @Override
    public void show(int a) {
        
        dao.show(a);
    }


    
}

dao的代码:

@Repository(value="userDao")
public class DaoImp implements Dao{

    @Override
    public void show(int a) {
        System.out.println("被调用========"+a);
        
    }

}

aop切面编程

所谓AOP, 叫做"代码插入式编程风格"好理解一点.在"对象风格编程"时代, 一发现有重复的代码, 人们就将这块代码抽出来成为一个类. 用这个类来管理这些代码.但是, 不是所有的重复代码都抽得出来, 有时需要在代码的前后插入.用对象抽象方法就非常麻烦.这时有人就想出一方法, 在编译时在这段代码的前后插入代码.有人给这个事情命名什么切面。

使用注解方式来完成切面编程

首先加入依赖 的jar包:

 

 

 创建一个切面类标记该类是切面类使用@Aspect,然后这个类还得创建一个对象,所以还得用@Controller的注解,相当于在xml文件中创建这个bean类,然后测试类中用ApplicationContext app=new ClassPathXmlApplicationContext("app.xml");来创建对象。因为切面类里面的方法是要被调用在主要的方法的前后的所以,用@Before这个注解表示在方法前调用,@After表示在方法后被调用,

还有@AfterReturning表示在方法执行后然后在经过返回值后调用该方法,@AfterThrowing表示方法出现异常会被调用该方法,如下代码:

package com.zhiyou100.lw.pie;

import java.lang.reflect.Array;
import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Controller;

@Aspect
@Controller(value="sunpie")
public class Sunpie {
    @Before(value="execution(* com.zhiyou100.lw.bean.*.*(..))")
    public void begin(JoinPoint jo) {
        Object[] args = jo.getArgs();
        String name=jo.getSignature().getName();
        System.out.println("方法前执行"+name+"参数有"+Arrays.asList(args));
    }
    @After(value="execution(* com.zhiyou100.lw.bean.*.*(..))")
    public void after(JoinPoint jo) {
        Object[] args = jo.getArgs();
        String name=jo.getSignature().getName();
        System.out.println("方法后执行"+name+"参数有"+Arrays.asList(args));
    }
    @AfterReturning(value="execution(* com.zhiyou100.lw.bean.*.*(..))",returning="a")
    public void aft(int a) {
        System.out.println("返回值"+a);
    }
    @AfterThrowing(value="execution(* com.zhiyou100.lw.bean.*.*(..))",throwing="e")
    public void aa(Exception e) {
        System.out.println("出错了");
    }
}

其中注解括号里面的value的值是,告诉程序那个位置用到了切面注解,前两个方法的括号里的

JoinPoint jo,获得JoinPoint这个类,然后调用这个类中的getArgs(),这个方法,获得object的数组的参数名,调用
getSignature().getName(),表示获得方法名。对于调用有返回值的日志,括号里面的是返回的数据类型,异常括号里面的是,异常类型,
测试类直接使用如下:
ApplicationContext app=new ClassPathXmlApplicationContext("app.xml");
        Sunfa s = (Sunfa) app.getBean("sunfaImp");
        s.add(20, 0);
app.xml,是配置文件,

sunfaImp,是目标类,接收必须用它的接口接参数,不然出错,我是调用自己的add方法的。

在配置文件中使用bean类的方法,来实现日志的打印

    <bean id="sunfaImp" class="com.zhiyou100.lw.bean.SunfaImp"></bean>
    <bean id="sunpie" class="com.zhiyou100.lw.pie.Sunpie2">
        
    </bean>
    <aop:config>
            <aop:pointcut expression="execution(* com.zhiyou100.lw.bean.*.*(..))" id="begin"/>
            <aop:aspect ref="sunpie">
            
                <aop:before method="begin" pointcut-ref="begin"/>
                <aop:after method="after" pointcut-ref="begin"/>
            </aop:aspect>
    </aop:config>

创建目标类和切面类,因为用到切面的格式所用,用aop标签  execution表示需要切点在哪个位置上,

<aop:aspect ref="sunpie">表示在那个切面里,
 <aop:before method="begin" pointcut-ref="begin"/>表示在需要切点的地方加入切面类的方法执行前的方法,和方法执行后的方法。
 
 

 

posted @ 2019-09-07 22:40  呦呀哦啦  阅读(102)  评论(0)    收藏  举报