Spring框架学习总结

一、spring环境搭建准备

hibernate的包
spring的包
mysql驱动包:mysql-connector-java-8.0.16.jar
日志包:commons-logging-1.1.1.jar
测试包:hamcrest-core-1.3.jar 和 junit-4.13-beta-2.jar
aop包:com.springsource.net.sf.cglib-2.2.0.jar 和 spring-aspects-4.0.0.RELEASE.jar
jdbc包 :c3p0-0.9.1.2.jar
jpa标准:hibernate-jar-2.0-api-1.0.1.fingl.jar

二、appllicationContext.xml使用

1.创建appllicationContext.xml文件

2.创建IOC容器

ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);  
//或者调用FileSystemXmlApplicationContext
//上述两种方法都继承于ConfigurableApplicationContext,定义了refresh()和close()

3.拿出bean对象

Student student = ctx.getBean(“beanId”);  //id 或 类型名

三、配置bean

1.bean基本结构,属性赋值,特殊数据结构定义

<bean id=”唯一标识” class=”全类名”>  <!--类必须有无参构造器-->
	<property name=”类属性” value=”值”></property>  <!--属性根据set方法注入-->
	<property name=”car” ref=”id”></property>  <!--引用类型传值-->
	<property name=”car”>
		<ref bean=”id”/>  <!--ref子节点-->
	</property>
	<property name=”car”>
		<bean class=”全类名”>  <!--内部bean-->
			<property name=”子bean属性” value=”值”>
		</bean>
	</property>
	<property name=”car.name” value=”aodi”></property>  <!--级联属性赋值-->
	<property name=”cars”>
		<list>  <!--list/set/array/map属性一样-->
			<ref bean=”id”/> 
		</list>
		<map>  <!--map-->
			<entry key=”aa” value-ref=”car”/> 
		</map>
	</property>
	<property name=”properties”>  <!--properties属性-->
		<props>
			<prop key=”user” value=”root”></prop>
		</props>
	</property>
</bean>

2.构造器赋值,结构单例

<bean id=”唯一标识” class=”全类名”>
	<constructor-arg value=”属性” (index=”0”)>
		</constructor-arg>  <!--通过构造器注入,标记,类型/(type=”java.long.String”)-->
	<constructor-arg (type=”java.long.String”)>
		<value><![CDATA[<shanghai>]]></value>  <!--value子节点,CDATA转译-->
	</constructor-arg>
	<constructor-arg><null/></constructor-arg>  <!--赋空值-->
</bean>

<util:list id=”cars”>  <!--单例集合,导入util命名空间-->
	<ref bean=”car1”>
	<ref bean=”car2”>
</util:list>

3.作用域,p赋值,自动装配,模板

<bean id=”person” class=”全类名” 
	scope=”singleton”
 	p:age=”50” p:name=”XX”      
	p:car-ref=”car” 
	abstract=”true”> 
	<!--scope:bean的作用域singleton默认单例,prototype原型-->
	<!--p赋值,导入p命名空间-->
	<!--级联字段cars或使用自动装配autowire=”byName/byType”-->
	<!--abstract模板(class属性没有就一定是抽象bean)-->
</bean>

<!--继承bean,depends-on依赖必须有car-->
<bean id=”person2” p:age=”60” depends-on=”car” parent=”person”></bean>

4.本地配置文件引用,SpEl

<!--引用外部配置文件-->
<context:property-placeholder location="classpath:db.properties"/>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="user" value="${user}"></property>   <!--引用格式-->
	<property name="pi" value="#{(java.lang.Math).PI*80}"></property><!--Spel:常量,方法,if:-->
</bean>
<!--高版本MySql注意配置的改动-->
driverClass=com.mysql.cj.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/bookStore?useSSL=false&serverTimezone=UTC

5.生命周期

<bean id=”person” class=”全类名”
	Init-method=”init”     
	Destory-method=”destory”
 	p:age=”50” 
 	p:name=”XX”>
 <!--Init-method 和 Destory-method bean的生命周期-->
</bean>

<bean class=”bean的后置处理器的全类名”></bean>  <!--继承BeanPostProcessor接口,
实现 postProcessBeforeInitialization(object bean, String beanName)
和 postProcessAfterInitialization(object bean, String beanName)-->

6.工厂方法

<bean id=”car” 
	class=”静态工厂全类名”
	factory-method=”getCar”>  <!--静态工厂方法-->
	<constructor-org value=”audi”></constructor-org>
</bean>

<bean id=”carFactory” class=”工厂全类名”</bean> 
<bean id=”car2”
	class=”实例工厂全类名”
	factory-method=”getCar”>  <!--实例工厂方法-->
	<constructor-org value=”ford”></constructor-org>
</bean>

<!--继承FactoryBean<T>,实现getObject,getObjectType,isSingletn方法-->
<bean id=”car” class=”bean工厂全类名”
	<property name=”brand” value=”BMW”></property>
</bean>

四、注解

<context:component-scan 
use-default-filter=”true” 
base-package=”全包名”  
resource-pattern=”repository/*.class”> 
<!--配置注解-->
<!--use-default-filter 默认true扫描全类,false不扫描-->
<!--base-package 注解生效区域-->
<!--resource-pattern 限制范围内只读repository-->
<context:exclude-filter type=”annotation”
Expression=”不包含的类”/>  <!--生效区域中排除类/annotation根据注解-->
<context:include-filter type=”annotation”  
Expression=”只包含的类”/>  <!--生效区域中包含类/assignable根据具体类-->
</context:component-scan> 
@Component
@Respository
@Service
@Controller(“value”)  //类注解,自动配置bean,value修改bean的id

@Autowired(required=false)  //字段or方法注解,自动装配bean,required无法装配则为null
@Qualifier(“beanName”)    //限定bean的id

泛型依赖注入,通过注解建立泛型之间的关系,子类会自动继承

五、AOP使用

1.代理使用

public class xxProxy {
	private xx target;    //要代理的对象
	public xxProxy(xx target) {
		super();
		this.target = target;
	}
	public xx getxxProxy(){	  //返回代理对象
		xx proxy = null;
		ClassLoader loader = target.getClass().getClassLoader();  //代理对象使用的类加载器
		Class [] interfaces = new Class[]{xx.class};  //类方法
		InvocationHandler h = new InvocationHandler() {  //方法代理执行语句
		//proxy: 代理对象。 一般不使用该对象,method: 正在被调用的方法,args: 调用方法传入的参数
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				String methodName = method.getName();
				//打印日志
				System.out.println("[before] The method " + methodName + 
					" begins with " + Arrays.asList(args));
				//调用目标方法
				Object result = null;
				try {
					//前置通知
					result = method.invoke(target, args);  //调InvocationHandler的invoke
					//返回通知, 可以访问到方法的返回值
				} catch (NullPointerException e) {
					e.printStackTrace();
					//异常通知, 可以访问到方法出现的异常
				}
				//后置通知. 因为方法可能会出异常, 所以访问不到方法的返回值
				//打印日志
				System.out.println("[after] The method ends with " + result);
				return result;
			}
		};
		proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
		return proxy;
	}
}

2.基于注解使用AOP

<!--加入使 AspjectJ 注解起作用的配置-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Order(2)  //执行顺序
@Aspect  //声明是一个切面
@Component
public class LoggingAspect {

	//1.前置通知
	@Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))")
	public void beforeMethod(JoinPoint joinPoint){   //joinPoint访问方法签名和方法参数
		String methodName = joinPoint.getSignature().getName();
		Object [] args = joinPoint.getArgs();
		System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
	}
	
	//2.@After("execution(* com.atguigu.spring.aop.*.*(..))") 后置通知	
	//3.@AfterReturning返回通知,(returning=”result”)
	//4.@AfterThrowing异常通知,(throwing=”ex”)
	//5.@Around环绕通知综合上面4种通知

	//@Pointcut(“xxx”) public void xx (){}  //切点表达式
	//@After(value=”xxx”)  //切点调用
}

3.基于配置文件使用AOP

<!-- 配置 bean -->
<bean id="xx" class="com.atguigu.spring.aop.xml.xx"></bean>

<!-- 配置切面的 bean -->
<bean id="loggingAspect" class="LoggingAspect全类名"></bean>
<bean id="vlidationAspect" class="VlidationAspect全类名"></bean>

<!-- 配置AOP -->
<aop:config>
	<!-- 配置切点表达式 -->
	<aop:pointcut expression="
		execution(* com.atguigu.spring.aop.xml.ArithmeticCalculator.*(int, int))" 
		id="pointcut"/>
	<!-- 配置切面及通知 -->
	<aop:aspect ref="loggingAspect" order="2">
	<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
	<aop:after method="afterMethod" pointcut-ref="pointcut"/>
	<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
	<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
	<aop:around method="aroundMethod" pointcut-ref="pointcut"/>
</aop:config>

六、使用JdbcTemplete

<!-- 配置 Spirng 的 JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property></bean>


<!-- 配置 NamedParameterJdbcTemplate, 没有无参数的构造器 -->
<bean id="namedParameterJdbcTemplate"
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dataSource"></constructor-arg></bean>
//使用JdbcTemplate
@Autowired
private JdbcTemplate jdbcTemplate;
public Employee get(Integer id){    //不支持级联属性映射
String sql = "SELECT id, last_name lastName, email FROM employees WHERE id = ?";
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);
Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, id);
  return employee;
}

List<Object[]> batchArgs = new ArrayList<>();
jdbcTemplate.batchUpdate(sql, batchArgs);

//使用NamedParameterJdbcTemplate
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);
namedParameterJdbcTemplate.update(sql, paramSource);

Map<String, Object> paramMap = new HashMap<>();
namedParameterJdbcTemplate.update(sql, paramMap);

七、使用事务

1.基于注解使用事务

<!-- 配置事务管理器 -->
<bean id="transactionManager" 
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property></bean>
<!-- 启用事务注解 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
//添加事务注解
	//1.使用 propagation 事务传播行为,默认REQUIRED/REQUIRES_NEW
	//2.使用 isolation 事务隔离级别, 最常用的取值为 READ_COMMITTED..
	//3.使用noRollbackFor	默认所有运行时异常回滚.
	//4.使用 readOnly 指定事务是否为只读. 默认false/true
	//5.使用 timeout 指定强制回滚之前事务可以占用的时间.  
	@Transactional(propagation=Propagation.REQUIRES_NEW,readOnly=false,timeout=3,
isolation=Isolation.READ_COMMITTED,noRollbackFor={UserAccountException.class})

2.基于配置使用事务

<!-- 2. 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
		<!-- 根据方法名指定事务的属性 -->
		<tx:method name="purchase" propagation="REQUIRES_NEW"/>
		<tx:method name="get*" read-only="true"/>
		<tx:method name="find*" read-only="true"/>
		<tx:method name="*"/>
	</tx:attributes>
</tx:advice>
	
<!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
<aop:config>
	<aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" 
		id="txPointCut"/>
	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>

八、整合Hibernate

在这里插入图片描述

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>  //生成表的策略
  </session-factory>
</hibernate-configuration>

在这里插入图片描述

<?xml version='1.0'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

   <class name="me2.untitled.Entity.Account" table="SH_ACCOUNT">
      <id name="id" type="java.lang.Integer">
         <column name="Id"/>
         <generator class="assigned"/>
      </id>
   </class>
</hibernate-mapping>

在这里插入图片描述

    <!--引用外部配置文件-->
    <!-- 配置本地包注解 -->
    <!-- 配置 DataSource -->
    <!-- 配置 Hibernate 的 SessionFactory -->
<!-- 配置 AspjectJ 注解 -->
<!-- 配置 SessionFactory -->
<bean id="SessionFactory" class=
"org.springframework.orm.hibernate5.LocalSessionFactoryBean">
     <property name="dataSource" ref="dataSource"></property>
     <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
     <property name="mappingLocations" value="classpath:me2/untitled/Entity/*.hbm.xml"></property></bean>

    <!-- 配置事务 -->
    <bean id="transactionManager" class=
"org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory"></property>
    </bean>
	<!-- 配置事务属性txAdvice -->
    <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->

在这里插入图片描述

	@Autowired
	private SessionFactory sessionFactory;

	//获取和当前线程绑定的 Session. 
	private Session getSession(){
		return sessionFactory.getCurrentSession();
	}

	@Override
	public int findBookPriceByIsbn(String isbn) {
		String hql = "SELECT b.price FROM Book b WHERE b.isbn = ?";
		Query query = getSession().createQuery(hql).setString(0, isbn);
		return (Integer)query.uniqueResult();
	}
//String hql2 = "SELECT b.stock FROM Book b WHERE b.isbn = ?";
//int stock = (int) getSession().createQuery(hql2).setString(0, isbn).uniqueResult();

//String hql = "UPDATE Book b SET b.stock = b.stock - 1 WHERE b.isbn = ?";
//getSession().createQuery(hql).setString(0, isbn).executeUpdate();

九、Web中使用spring

1.基本实现

1.listeners监听

public class SpringServletContextListener implements ServletContextListener {
    public SpringServletContextListener() {}
    public void contextDestroyed(ServletContextEvent arg0) {}
    public void contextInitialized(ServletContextEvent arg0) {
    	//1. 获取 Spring 配置文件的名称
    	ServletContext servletContext = arg0.getServletContext();
    	String config = servletContext.getInitParameter("configLocation");
    	//2. 创建 IOC 容器
    	ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
    	//3. 把 IOC 容器放在 ServletContext 的一个属性中
    	servletContext.setAttribute("ApplicationContext", ctx);
    }	
}

2.servlets小服务

public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
		//1. 从 application 域对象中得到 IOC 容器的引用
		ServletContext servletContext = getServletContext();
		ApplicationContext ctx = (ApplicationContext) servletContext.getAttribute("ApplicationContext");
		//2. 从 IOC 容器中得到需要的 bean
		Person person = ctx.getBean(Person.class);
		person.hello();
	}
}

3.配置文件中创建servielt bean
4.添加jsp页面

2.调用spring的接口实现

Web.xml

	<!-- 配置 Spring 配置文件的名称和位置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<!-- 启动 IOC 容器的 ServletContextListener -->
	<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

十、整合strut2

1.导入struts2包

2.在web.xml中加入struts2的web的Filter配置

<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<ilter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

3.加入struts2.xml
4.配置文件配置Action的bean
5.struts2.xml中配置页面调用bean来创建Action

<action name="person-save" class="personAction">
	<result>/success.jsp</result>
</action> 

6.加入 struts2-spring-plugin-2.3.15.3.jar,Struts2 会先从 IOC 容器中获取 Action 的实例

引用

 [1]: http://www.gulixueyuan.com/my/course/46
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值