一篇文章入门Spring框架

Spring是个容器,可以用来管理bean对象

如果没有使用Spring,我们要使用对象时需要自己手动new 一个对象出来
获取对象之前需要配置Spring(ApplicationContext.xml):

<!---->

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
	
	<!--在spring配置中加入bean配置 class为类路径-->
	<bean name="user" class="com.echo.bean.User"></bean>
	
</beans>

然后在代码加载配置文件,向spring申请一个User对象:


ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
User bean = (User)ac.getBean("user");//根据id获取User对象,每次获取的对象都是同一个

那么如何给配置在xml文件里对象赋值?可以使用依赖注入(就是在xml文件里事先配置好属性地值):

<bean name="user" class="com.echo.bean.User">
	<property name="u_id" value="5"></property>
</bean>

web项目中地依赖关系:
在这里插入图片描述

Spring-Ioc | DI 概念:(要实现IOC依赖DI的支持 )

IoC:反转控制
反转:将我们自己创建对象的工作交给Spring容器帮我们完成
控制:就是有Spring帮我们负责创建销毁对象,掌控对象的生命周期,我们在需要使用对象的时候跟Spring申请即可
IOC是一种编程思想,也是一种新的设计模式,它将帮助我们管理对象,它需要DI(依赖注入)技术的支持,维护依赖关系

DI:依赖注入
将值通过配置的方式为变量初始化 / 赋值(注入)

Spring配置:

xml配置:
bean元素:交由Spring管理的对象都要配置在bean标签中
Bean的创建的方式:无参构造(常用)、静态工厂、动态工厂,默认使用无参构造方法构造,如果没有无参构造器,会报错

bean标签属性:
lazy-init(懒加载):
在ClassPathXmlApplicationContext对象创建时,容器中的所有对象都会被自动创建
如果配置大量的bean,会导致内存过大
Spring推出了延迟加载解决这一问题(懒加载):

<!---->
<!--就是直到要使用时才加载-->
	<bean name="user" class="com.echo.bean.User" lazy-init="true">
		<property name="u_id" value="5"></property>
	</bean>

scope:
singleton(常用):单例模式(默认)
prototype(特殊时使用):多例模式(每次申请都新构造一个新的对象,如果使用该属性值,创建的对象就会交给程序员管理,不再由Spring管理)
request(不常用):在web环境下,如果scope属性为request,那么这个对象被创造出来时。它的生命周期会与request一致
session(不常用):同理,生命周期与session一致

初始化方法Init-method和销毁方法destroy-method
Init-method:如果对象需要在创建后调用一些初始化方法(非构造器),可以使用这个属性设置
destroy-method:如果对象在销毁前需要调用一些方法(例如释放资源),可以使用这个属性设置,该方法在容器关闭后激活(单例模式有效)

Spring属性注入:(在xml中配置属性)

Setter方法注入:如果要注入属性,则类中必须要有属性对应的Setter方法
引用类型(自定义类型):如果对象中包含另一个对象的引用(自定义类型),则需要再同级标签下再配置一个该类型的bean,然后在主对象中使用ref关联起来:

<bean name="user" class="com.echo.bean.User">
	<property name="u_id" value="5"></property>
	<property name="u_username" value="echo"></property>
	<property name="pet" ref="pet"></property>
</bean>
	
<bean name="pet" class="com.echo.bean.Pet">
	<property name="name" value="mypet"></property>
</bean>

构造方法注入:利用带参构造器注入
无参构造器是必须提供的,spring用无参构造器创建对象
构造方法注入只是将属性注入

<!--要把构造器所有的参数都配置上-->
<bean name="userplus" class="com.echo.bean.User">
	<constructor-arg name="u_username" value="abc" type="java.lang.String"></constructor-arg>
	<constructor-arg name="u_password" value="abc" type="java.lang.String"></constructor-arg>
</bean>

复杂类型注入(Array、List、Set、Map、Properties):
示例:被注入的java类:

public class Col {
//以下getter、setter省略
	private Object[] array;
	private ArrayList list;
	private Map map;
	private Properties properties;
	private Set set;
}

bean注入配置

<!---->
<!--数组使用array,列表使用list,键值对使用map\props-->
	<bean name="col" class="com.echo.bean.Col">
		<property name="array">
			<array>
				<!--内容使用value标签包围-->
				<value>123</value>
				<value>abc</value>
				<!--可以指定内容为引用类型-->
				<ref bean="pet" />
			</array>
		</property>
		<property name="list">
			<list>
				<value>listtiem1</value>
				<value>listtiem2</value>

			</list>
		</property>

		<property name="set">
			<set>
				<value>setitem1</value>
				<value>setitem2</value>

			</set>
		</property>

		<property name="map">
			<map>
				<!--map内容使用entry包围,在其中设置key和value-->
				<entry key="A" value="a"></entry>
				<entry key="B" value="b"></entry>
				<!--同样可以设置引用类型的key和value-->
				<entry key-ref="user" value-ref="pet"></entry>
			</map>
		</property>

		<property name="properties">
			<props>
				<!--prop的value直接写在标签里-->
				<prop key="name">root</prop>
				<prop key="password">123456789</prop>
			</props>
		</property>
	</bean>
Spring注解配置:

可以使用注解配置将对象交给Spring管理,首先要打开基本扫描:

<!-- 开启组件扫描 base-package扫描该包下以及子包的所有注解-->
<context:component-scan base-package="com.echo.bean"></context:component-scan>
	

打开这个Spring就会自动扫描包下的所有注解
Spring注解:
@Component():
在类定义的顶上加入该注解,则会将该类的实例交给Spring管理,例如:

@Component("user2")
public class User2 {
...
}

Spring为了区分对象在不同层的注解使用了以下注释:

//功能和@Component("user2")一样,只是名称不同,有利于区分
@Controller("user2") //对应web层
@Service("user2")	//对应service层
@Repository("user2")	//对应Dao层

@Scope:
使用方式:
将值赋值给scopeName,也可以省略scopeName

@Scope(scopeName = "prototype")
public class User2 {
...
}

@PostConstruct:
在构造器调用后调用

@PreDestroy:
在对象销毁前调用

Spring注解注入:

@Value():
注入基本数据,可以给成员变量注解,也可以给方法注解,如果成员变量私有,推荐在setter方法上使用该注解。

@Resource和@Autowired:
以上两种注解用来输入引用数据,作用是可以消除代码中的setter和getter,还有bean中的properties属性
@Autowired:
自动装配,如果设置该注解,Spring会自动在管理的类中按照查找同类型的实例,并填装上,如果找到多个或没有找到,就报错。

@Resource:
功能同上,需要设置name,用来指定填装的实例,而不是自动查找,比Autowired推荐使用。

Spring集成的JUnit测试:
@RunWith(SpringJUnit4ClassRunner.class)//使用junit进行测试,帮我们创建容器
@ContextConfiguration("classpath:ApplicationContext.xml")
public class SpringJunit {

	//可以直接从容器中获取对象
	@Resource(name = "user")
	private User user;
	
	@Test
	public void test() {
		System.out.println(user);
	}
	
	
}
Spring分包配置:

如果有多个配置文件
可以通过import将某个配置文件添加到其他配置文件中

<!--导入其他配置文件-->
<import resource="ApplicationContext.xml"/>
配置Spring随项目启动:

在web.xml中加入监听器配置:

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:ApplicationContext.xml</param-value>
</context-param>

然后可以在java中调用容器:

WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
Spring-aop中的一些名词:

JoinPoint: 连接点。目标对象中,那些方法会被拦截
Pointcut: 切入点。筛选连接点,最终要增强的方法
Advice: 通知/增强。增强代码
Introduction: 介入。和增强类似(执行期动态加入)
Aspect: 切面。通知 + 增强
target: 目标。被代理对象
weaving: 织入。把切面的代码应用到目标对象来创建新的代理对象
proxy: 代理。把切面的代码引用到目标对象来创建新的代理对象

Spring-aop自定义通知类型:

before 前置通知
after 最终通知(后置通知)
afterReturning 成功通知(后置通知)
afterThrowing 异常通知(后置通知)
around 环绕通知

使用配置使用上述通知:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">

	<!-- 目标对象,需要增强/代理的对象 -->
	<bean name="userService"
		class="com.echo.testservice.UserServiceImpl"></bean>

	<!-- 通知对象,里面包含通知/增强的方法 -->
	<bean name="myAdvice" class="com.echo.aop.MyAdvice"></bean>


	<aop:config>
		<!-- 切入点 expression:切入点表达式,可以配置要增强的方法,id是唯一标识
		不能有参数
		* com.echo.testservice.UserServiceImpl.*(..)
		* 标识全匹配,..表示任何参数
		-->
		<aop:pointcut expression="execution(* com.echo.testservice.UserServiceImpl.*(..))" id="servicePc" />

		<!-- 切面 通知+切入点 -->
		<aop:aspect ref="myAdvice">
			<aop:before method="before" pointcut-ref="servicePc"/>
			
			<!-- 最终注释 后置通知-->
			<aop:after method="after" pointcut-ref="servicePc"/>
			
			<!-- 成功通知 后置通知 -->
			<aop:after-returning method="afterReturning" pointcut-ref="servicePc"/>
			
			<!-- 异常通知 后置通知 -->
			<aop:after-throwing method="afterThrowing" pointcut-ref="servicePc"/>
			
			<!-- 环绕通知  -->
			<aop:around method="around" pointcut-ref="servicePc"/>
		</aop:aspect>
	</aop:config>
</beans>
配置Spring-aop事务示例:

配置事务核心管理器:

<!---->
<!-- 配置事务核心管理器:配置事务核心管理器,首先要先配置数据库实例 -->
<!--c3p0-->
<bean name="dataSource"
	class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
	<property name="jdbcUrl"
		value="jdbc:mysql://localhost:3306/spring"></property>
	<property name="user" value="root"></property>
	<property name="password" value="123456789"></property>
</bean>

<!--然后将数据库实例注入管理器-->
<bean name="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>
</bean>

配置事务通知:

<!---->
<!-- 事务通知 -->


<tx:advice id="txAdvice"

	transaction-manager="transactionManager"><!--为事务配置事务管理器-->
	
	<tx:attributes><!--配置事务的相关属性-->
	<!--在attributes中配置事务相关的操作数据库的方法:
	
	name:需要配置事务的含有Sql操作的方法名称
	isolation:隔离级别
	propagation:Spring特有的事务传播,一般可以使用默认的REQUIRED
	read-only:是否只读,如果有需要写入数据库,为false
	
	-->
		<tx:method name="transferAccounts" isolation="DEFAULT"
			propagation="REQUIRED" read-only="false" />
	</tx:attributes>
</tx:advice>
<!--此时事务没有绑定切入点-->

配置aop:

<!-- 配置aop:绑定切入点 -->
<aop:config>
	<!-- 配置切入点 -->
	<aop:pointcut
		expression="execution(* com.echo.service.AccountServiceImpl.*(..))"
		id="txPc" />
	
		<!--配置为创建好的通知器关联切入点-->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>
发布了68 篇原创文章 · 获赞 12 · 访问量 5204

猜你喜欢

转载自blog.csdn.net/qq_40963076/article/details/105010616