spring框架的相关问题
环境的搭建
下面展示一些 内联代码片
。
首先是在idea中建一个maven项目,然后在pom.xml文件中导入
下面的依赖,这个代码需要放到dependencies标签下,
如果要是报红就进入file->setting->maven里勾选Always
update snapshots选项,也就是自动从远程下载或者获取本地
的jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.14.RELEASE</version>
</dependency>
下面展示一些 内联代码片
。
接着还要修改spring.xml里的jdk版本,这个看你的jdk版本是
多少,就配置多少,我的是1.8,这个是maven项目创建时就有的
,只不过显示的是1.7,需要自己手动更改
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
IOC的bean对象实例化以及底层原理的分析
IOC的手动注入
所有的类在com.xxx.service02包下
TypeDao类
TypeService类
service类
xml文件在resource资源目录下
spring.xml配置文件
下面展示一些 内联代码片
。
TypeDao类
package com.xxx.service02;
public class TypeDao {
public void test(){
System.out.println("hello dao");
}
}
下面展示一些 内联代码片
。
TypeService类,将Type注入到这个类里边
package com.xxx.service02;
public class TypeService {
/**
* 手动注入的四种方式,这里只展示两种,后面两种不常用
* set方法注入
* 构造器方式注入
* 静态工厂注入
* 实例化工厂注入
*
* 其中set方式注入最为常用
* 构造器注入可以在构建对象的同时一并完成依赖关系,也就是对象一建立,则所有的一切就创建好了,但是如果你要创建的对象很多的话,
* 你使用构造器传的参数就会有很多,而且不容易记忆,所以还是推荐set方法注入
*/
// 1.
// private TypeDao typeDao = new TypeDao();
/**
* set方法注入
* 需要给属性字段提供set方法
*/
// private TypeDao typeDao;
//
// public void setTypeDao(TypeDao typeDao) {
// this.typeDao = typeDao;
// }
//
字符串类型注入
// private String host;
//
//
// public void setHost(String host) {
// this.host = host;
// }
整型注入
// private Integer prot;
// public void setProt(Integer prot) {
// this.prot = prot;
// }
Map ...
// public void test(){
// System.out.println("hello service");
// typeDao.test();
// System.out.println("host:"+host+" prot:"+prot);
// }
/**
* 构造器注入
* 有一个缺点:我既要注入你,你又要注入我,就会报错
* set方法可以解决这个缺点
*/
private TypeDao typeDao;
// public TypeService(TypeDao typeDao ) {
// this.typeDao=typeDao;
// }
public TypeService(TypeDao typeDao) {
this.typeDao=typeDao;
}
public void test(){
System.out.println("hello service");
typeDao.test();
// System.out.println("host:"+host+" prot:"+prot);
}
}
下面展示一些 内联代码片
。
service类,通过这个类进行加载配置文件实例化出bean对象。核心类
package com.xxx.service02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class service {
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("spring.xml");
TypeService typeService=(TypeService)app.getBean("typeService");
typeService.test();
}
}
下面展示一些 内联代码片
。
spring.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 普通的加载配置文件-->
<!-- <bean id="userService" class="com.xxxx.service.UserService"></bean>-->
<!-- set方式注入:
name:属性字段的名字
red:对应bean标签的id属性值
value:具体的属性值
-->
<!-- <bean id="typeDao" class="com.xxx.service02.TypeDao" />-->
<!-- <bean id="typeService" class="com.xxx.service02.TypeService">-->
<!-- 通过property属性进行set方法注入-->
<!-- <property name="typeDao" ref="typeDao" />-->
<!-- 字符串类型注入-->
<!-- <property name="host" value="localhost"/>-->
<!-- 整型注入-->
<!-- <property name="prot" value="8080"/>-->
<!-- </bean>-->
<!-- 构造器方式注入
通过constructor-arg标签来注入
name
ref:对应bean标签的id属性值
value
index:参数的下标
-->
<bean id="typeDao" class="com.xxx.service02.TypeDao" />
<bean id="typeService" class="com.xxx.service02.TypeService">
<!-- 构造器注入-->
<constructor-arg name="typeDao" ref="typeDao"/>
<!-- <constructor-arg name="host" value="localhost"/>-->
<!-- <constructor-arg name="prot" value="8080"/>-->
</bean>
<!-- p命名空间的使用
在beans里需要加入 smlns:p="http://www.springframeword.org/schema/p"
<bean id="typeDao" class="com.xxx.service02.TypeDao" />
<bean id="typeService" class="com.xxx.service02.TypeService" p:typeDao-ref="typeDao"/>
-->
</beans>
IOC的自动注入
1.使用Resource注解的自动注入
所有的类在com.xxx.service03包下
UserDao类
UserService类
service类
xml文件在resource资源目录下
spring03.xml配置文件
下面展示一些 内联代码片
。
UserDao类
package com.xxx.service02;
public class TypeDao {
public void test(){
System.out.println("hello dao");
}
}
下面展示一些 内联代码片
。
UserService类,将UserDao通过配置文件spring03.xml
注入到这个类里边
package com.xxxx.service03;
import javax.annotation.Resource;
public class UserService {
/**
* @Resource注解
* 实现bean对象的自动注入(默认是set自动注入)
* 1.默认会根据bean标签的id属性值查找(属性字段名与bean标签的id属性值相等)
* 2.如果属性名称没有找到,会根据类型进行查找
* 例如:private UserDao userDao1 在spring03.xml中就会根据类型进行查找
*
* 3.注解可以写在set方法上和属性字段,一般都不会写set方法,所以都写在属性字段上
*
* 4.注解可以有name属性值,原因:
* 因为存在多个类实现了同一个接口,然后属性字段值又跟id名不一样,这个时候会根据
* 类型进行查找,就会出现错误。name属性的出现就是为了解决这个问题,name属性值跟
* spring03.xml里的bean的id一样
*/
// 1.默认会根据bean标签的id属性值查找(属性字段名与bean标签的id属性值相等)
// @Resource
// private UserDao userDao;
//
// public void test(){
// System.out.println("hello userService");
// userDao.test();
// }
// 2.如果属性名称没有找到,会根据类型进行查找
// @Resource
// private UserDao userDao1;
//
// public void test(){
// System.out.println("hello userService");
// userDao1.text();
// }
//3.注解可以写在set方法上和属性字段,一般都不会写set方法,所以都写在属性字段上
// private UserDao userDao;
// @Resource
// public void setUserDao(UserDao userDao) {
// this.userDao = userDao;
// }
//
// public void test(){
// System.out.println("hello userService");
// userDao.text();
// }
// 4.注解可以有name属性值,原因:
// * 因为存在多个类实现了同一个接口,然后属性字段值又跟id名不一样,这个时候会根据
// * 类型进行查找,就会出现错误。name属性的出现就是为了解决这个问题,name属性值跟
// * spring03.xml里的bean的id一样
// @Resource(name="ud") //这里配置文件里的bean里的id要跟这个name值相等
@Resource
private UserDao userDao;
public void test(){
System.out.println("hello userService");
userDao.text();
}
}
下面展示一些 内联代码片
。
service类,通过这个类进行加载配置文件实例化出bean对象。
核心类
package com.xxxx.service03;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Service {
public static void main(String[] args) {
ApplicationContext bean=new ClassPathXmlApplicationContext("spring03.xml");
UserService userService=(UserService)bean.getBean("userService");
userService.test();
/**
* 扩充spring里的bean标签是单例的
*/
UserService userService1=(UserService)bean.getBean("userService");
UserService userService2=(UserService)bean.getBean("userService");
System.out.println(userService1);
System.out.println(userService2);
/**
* 运行结果:com.xxxx.service03.UserService@77ec78b9
* com.xxxx.service03.UserService@77ec78b9
* 说明实例化的对象是单例的
*/
}
}
下面展示一些 内联代码片
。
spring03.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启自动注入-->
<context:annotation-config/>
<bean id="userDao" class="com.xxxx.service03.UserDao"/>
<bean id="userService" class="com.xxxx.service03.UserService"></bean>
<!-- <bean id="ud" class="com.xxxx.service03.UserService"></bean>-->
</beans>
2.使用Auto注解的自动注入
跟Resource差不多
* 只有一点就是注解如果需要设置名字Qualifier(value="属性名")
* @Autowired
* @Qualifier(value="td")
package com.xxxx.service04;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.Resource;
public class UserService {
/**
* @Autowired注解
* 事项bean对象的自动注入
* *********跟Resource差不多
* 只有一点就是注解如果需要设置名字Qualifier(value="属性名")
* @Autowired
* @Qualifier(value="td")
*/
@Autowired
@Qualifier(value="td")
private UserDao userDao;
public void test(){
System.out.println("hello userService");
}
}
IOC的自动扫描
IOC实现的登录功能
IOC的作用域和生命周期
定时任务
AOP的静态代理
AOP的动态代理
jdk动态代理
CGLIB动态代理
AOP
AOP的注解实现和XML实现
一个包下com.aopAnnotations.
aspectj
LogCut.java面向切面的类
service
UserService.java
starter.java
一个spring配置文件
springAop.xml
LogCut.java
package com.aopAnnotations.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component //交给IOP实例化
@Aspect //定义当前类是一个切面类
public class LogCut {
/**
* 定义切入点
* 通过@Pointcut定义切入规则
* 1.拦截所有的方法 @Pointcut("execution(*(..))")
* 2.拦截所有公用的set方法 @Pointcut("execution(public set*(..))")
* 3.拦截com.aopAnnotations.service包下所有类的方法
* @Pointcut("execution(* com.aopAnnotations.service.*.*(..))")
* 3.拦截com.aopAnnotations.service包及其子包下所有类的方法
* * @Pointcut("execution(* com.aopAnnotations.service..*.*(..))")
*/
// @Pointcut("execution(* com.aopAnnotations.service.*.*(..))")
public void cut(){
}
// @Before(value="cut()")
public void before(){
System.out.println("前置通知");
}
// @AfterReturning(value="cut()")
public void afterReturn(){
System.out.println("返回通知.....");
}
// @After(value="cut()")
public void after(){
System.out.println("最终通知");
}
/**
* 异常通知 应用到切入点上
* 目标方法执行异常时
* @param e
*/
// @AfterThrowing(value = "cut()" , throwing = "e")
public void afterThrow(Exception e){
System.out.println("异常通知"+e.getMessage());
}
// @Around(value = "cut()")
public Object around(ProceedingJoinPoint pjp){
System.out.println("前置通知...");
Object result = null;
try {
result = pjp.proceed();
System.out.println("返回通知....");
}catch(Exception e){
e.printStackTrace();
System.out.println("异常通知....");
} catch (Throwable throwable) {
throwable.printStackTrace();
}finally{
System.out.println("最终通知...");
}
return result;
}
}
UserService.java
package com.aopAnnotations.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void test(){
System.out.println("userService...");
}
}
starter.java
package com.aopAnnotations;
import com.aopAnnotations.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.jws.soap.SOAPBinding;
public class starter {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("springAop.xml");
UserService userService =(UserService) app.getBean("userService");
userService.test();
}
}
下面展示一些 内联代码片
。
springAop.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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">
<!-- 设置扫描器-->
<context:component-scan base-package="com.aopAnnotations"/>
<!-- 注解实现aop自动代理-->
<!-- <aop:aspectj-autoproxy/>-->
<!-- xml实现aop自动代理-->
<aop:config>
<aop:aspect ref = "logCut">
<aop:pointcut id="cut" expression="execution(* com.aopAnnotations.service.*.*(..))"/>
<aop:before method="before" pointcut-ref="cut"/>
<aop:after-returning method="afterReturn" pointcut-ref="cut" />
<aop:after-throwing method="afterThrow" throwing = "e" pointcut-ref = "cut" />
<aop:after method="afterReturn" pointcut-ref="cut" />
<aop:around method="around" pointcut-ref="cut" />
</aop:aspect>
</aop:config>
</beans>