Spring框架入门

Spring中的IOC思想

Spring中的IOC,英文全称为Inversion of control,意思为控制反转。什么意思呢?我们可以具体说说,在一开始接触Java的时候,我们都是使用new来手动创建一个对象的,但是IOC思想就是让Spring容器帮我们创建好对象,我们直接使用即可,在代码里面很直观的体现就是我们很少看到new 的存在(当然我们配置文件的时候还是需要的)。
一个小小的demo:
首先是xml配置文件(写的有点杂,核心的就是开头的几行代码,后面的是一些想关的p标签、c标签以及一些方法的应用)

<?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:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsdspring-context.xsd">
        <!--    无参构造-->
    <bean id="user" class="com.Tom.pojo.User" name="user3,user4">
        <property name="name" value="Spring"/>
    </bean>
            <!--    别名-->
    <alias name="user" alias="user2"/>
    <!-- 使用p标签的无参构造 -->
<!-- <bean id="user" class="com.ztLin.pojo.User" p:name="Tom"/> -->
    <!--    有参构造的三种方法-->
<!--    <bean id="user" class="com.Tom.pojo.User">-->
<!--        <constructor-arg index="0" value="123"/>-->
<!--    </bean>-->
<!--    <bean id="user" class="com.Tom.pojo.User">-->
<!--        <constructor-arg type="java.lang.String" value="123"/>-->
<!--    </bean>-->
<!--    <bean id="user" class="com.Tom.pojo.User">-->
<!--        <constructor-arg ref=""/>-->
<!--    </bean>-->
    <!--  使用c标签的有参构造-->
<!--    <bean id="user" class="com.Tom.pojo.User" c:_0="Tom"/>     -->
</beans>

接下来是Java的测试类

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) context.getBean("user");
        System.out.println(user.toString());
    }
}

我们在使用user的时候就最直接从Spring容器中取出这个user对象就可以了,看起来好像变化不大,但其实使得对象在容器中创建,修改代码只需要修改配置文件即可。

Spring中的AOP思想

Spring中的AOP,英文全称为Aspect-oriented Programming,意思为面向切面编程。那么切面又是一个什么概念呢?在这里先引入一个纵向编程的概念,个人理解的纵向编程就是在从上往下,逐层递进编程,比如做一个JavaWeb项目,首先我们需要编写实体类,DAO层,Service层,Servlet层…切面就可以理解为这一个一个的层,面向切面编程就是在完成纵向编程之后,比如我们需要增加一个日志Log功能,那么我们在不改变Service这一层代码的情况下增加一个可以复用的功能。
Spring中的AOP是基于动态代理实现的,而动态代理又是通过反射实现的。但是呢,Spring是Java程序员的春天嘛,它作为一个简单易用的容器,当然也就帮我们屏蔽掉一些细节啦。
一共有三种方式实现AOP,下面可以看看简略版本!

使用注解@Aspect

我们可以使用xml进行配置,比如说要在执行一个方法的前后增加两个功能,当然也需要实现的Java需要的操作。(第一句开启springAOP注解一定不要忘啦!)

<aop:aspectj-autoproxy/>
<bean id="annotationPointCut" class="com.Tom.diy.AnnotationPointCut"/>

下面是Java的代码:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AnnotationPointCut {
    @Before("execution(* com.Tom.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("方法执行前!");
    }
    @After("execution(* com.Tom.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("方法执行后!");
    }
    @Around("execution(* com.Tom.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("环绕前");
        Object o = jp.proceed();
        System.out.println("环绕后");
    }
}

使用diy的方法加上xml配置

在标签中配置before标签和after标签

<aop:config>
    <aop:aspect ref="diy">
        <aop:pointcut id="point" expression="execution(* com.Tom.service.UserServiceImpl.*(..))"/>
        <aop:before method="before" pointcut-ref="point"/>
        <aop:after method="after" pointcut-ref="point"/>
    </aop:aspect>
</aop:config>

然后就是我们的diy类

public class diy {
    public void before(){
        System.out.println("这是方法执行前!");
    }
    public void after(){
        System.out.println("这是方式执行后!");
    }
}

使用继承接口和xml配置

在xml配置文件中,我们注册并使用before和after两个bean

<bean id="log" class="com.Tom.log.Log"/>
<bean id="afterLog" class="com.Tom.log.AfterLog"/>
<aop:config>
    <aop:pointcut id="pointcut" expression="execution(* com.Tom.service.UserServiceImpl.*(..))"/>
    <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>

然后再com.Tom.Log中我们创建如下两个类

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterLog implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("执行了"+method.getName()+",执行的结果为:"+o);
    }
}
import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class Log implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了!");
    }
}

上述的方法使得我们不必要每次都去修改每一层(切面)的代码,交给AOP来代理,配置完可以在不改变原有层代码的基础上增加重复的功能。

Spring中的一些常用注解

@Autowired

@Autowired对应的是自动装配的功能,自动装配就是说比如在applicationContext中我们注册了三个Bean,一个human,一个为cat,一个为dog,而human中有cat、dog这个属性,如果你在human中cat、dog属性的上方打上@Autowired这个注解,那么在Spring中就不必在human的配置中声明他的dog和cat是对应哪个,但如果同时有多个dog和cat,则必须通过配合@Qualifier(value=“XXX”),cat和dog在bean中绑定的名称实现自动装配。在applicationContext中进行如下配置

    <bean id="cat" class="com.Tom.pojo.Cat"/>
    <bean id="dog" class="com.Tom.pojo.Dog"/>
    <bean id="human" class="com.Tom.pojo.Human" p:name="XXX"/>

在Human类中,进行如下配置即可

public class Human {
    @Autowired
    @Qualifier(value="cat")//这里可以省略,也可以在set方法上自动装配
    private Cat cat;
    @Autowired
    private Dog dog;
    }

@Nullable

@Nullable是允许当前属性的值为

    @Nullable
    public String name ;

@Resource

@Resource注解和@Autowired这个注解的作用有些相似,都是自动装配,但是它是先按照名称来装配,与@Autowired不同(先类别,后名称),不是spring的原生注解,但由于与@Autowired相似,故放在一起。

	@Resource(name="cat")
    private Cat cat;

这里有一个小坑,annotation需要导入的maven依赖是

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.1</version>
</dependency>

不是

 <dependency>
     <groupId>javax.annotation</groupId>
     <artifactId>jsr250-api</artifactId>
     <version>1.0</version>
 </dependency>

@Component

@Component注解使用后会被加载到IOC容器中,

	@Component
	public class Human{}

与bean的作用相似。相当于下面的代码

<bean id="human" class="com.Tom.pojo.Human" p:name="XXX"/>

但是一定要记得加上扫描的包

 <context:component-scan base-package="com.Tom"/>

@Value

@Value可以使用在属性或者对应属性的set方法上,实现值的设置。

	@Value("Tom")
	private String name;

或者

    @Value("Tom")
    public void setName(String name) {
        this.name = name;
    }

@Controller

@Controller注解用来标注控制层,与Component的一样都会被加载到IOC容器。(注入服务)

	@Controller
	public class UserController {}

@Service

@Service注解标注服务层,主要用来进行业务的逻辑处理,与Component的一样都会被加载到IOC容器。(注入DAO)

	@Service
	public class UserService {}

@Repository

@Repository注解标记数据访问层,与Component的一样都会被加载到IOC容器。(实现DAO访问)

	@Repository
	public class UserDao {}

@Scope

@Scope注解为指定作用域,可以指定为singleton单例模式、prototype原型模式,一般来说,在单线程使用singleton节约资源,多线程使用prototype实现高并发。(默认为singleton

@Component
@Scope("singleton")
public class User {
    @Value("注解")
    public String name ;
}

下面总结一下使用Spring过程中遇到的坑

导包出错,比如使用注解开发

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.1</version>
</dependency>

这个才是正确的的annotation包(所以说该到maven官网查咱就别省了这一步)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值