1. spring环境搭建准备
//所有hibernate的lib包
//所有spring的lib包
//mysql驱动包
//日志包
//测试包
* com.springsource.net.sf.cglib-2.2.0.jar
* spring-aspects-4.0.0.RELEASE.jar
//aop包
//jdbc连接包
//jpa连接标准
//在web上使用spring的包
2.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/类型名
3.配置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”)(type=”java.long.String”)></constructor-arg> //通过构造器注入,标记,类型
<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” //bean的作用域singleton默认单例,prototype原型
p:age=”50” p:name=”XX” //p赋值,导入p命名空间
p:cars-ref=”cars”(/autowire=”byName”) //autowire引用类属性的自动装配/byType
abstract=”true”> //abstract模板(class属性没有就一定是抽象bean)
</bean>
<bean id=”person2” p:age=”60” depends-on=”car” parent=”person”></bean> //继承bean,depends-on依赖必须有car
4.本地配置文件引用,SpEl
<context:property-placeholder location="classpath:db.properties"/> //引用本地配置文件,引用context命名空间
<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>
driverClass=com.mysql.cj.jdbc.Driver //高版本MySql注意配置的改动
jdbcUrl=jdbc:mysql://localhost:3306/bookStore?useSSL=false&serverTimezone=UTC
5.生命周期
<bean id=”person” class=”全类名”
Init-method=”init” //bean的生命周期
Destory-method=”destory”
p:age=”50” p:name=”XX”>
</bean>
<bean class=”bean的后置处理器的全类名”></bean> //继承BeanPostProcessor接口,抛
BeanException异常,实现postProcessBeforeInitialization(object bean, String beanName)和 postProcessAfterInitialization
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>
4.注解
<context:component-scan //配置
use-default-filter=”true” //默认true扫描全类,false不扫描
base-package=”全包名” //注解生效区域
resource-pattern=”repository/*.class”> //限制范围内只读repository的id
<context:exclude-filter type=”annotation” //生效区域中排除类/annotation根据注解
Expression=”不包含的类”/>
<context:include-filter type=”annotation” //生效区域中排除类/assignable根据具体类
Expression=”只包含的类”/>
</context:component-scan>
@Component@Respository
@Service@Controller(“value”) //类注解,自动配置bean,value修改bean的id
@Autowired(required=”false”) //字段or方法注解,自动装配bean,required无法装配则为null
@Qualifier(“beanName”) //限定bean的id
//泛型依赖注入,通过注解建立泛型之间的关系,子类会自动继承
5.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
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> //加入使 AspjectJ 注解起作用的配置
@Order(2) //执行顺序
@Aspect //声明是一个切面
@Component
public class LoggingAspect {
//前置通知
@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));
}
@After("execution(* com.atguigu.spring.aop.*.*(..))") //后置通知
//@AfterReturning返回通知,(returning=”result”)
//@AfterThrowing异常通知,(throwing=”ex”)
//@Around环绕通知综合上面4种通知
}
@Pointcut(“xx”) public void xx (){} //切点表达式
@After(value=”xx”) //切点调用
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: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>
6.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);
7.事务使用
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>
7.整合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();
8.Web中使用spring
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);
}
}
//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();
}
}
//配置文件中创建servielt bean
//jsp页面
2.接口实现
//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>
9.整合strut2
//导入struts2包
//在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>
//加入struts2.xml
//配置文件配置Action的bean
//struts2.xml中配置页面调用bean来创建Action
<action name="person-save" class="personAction">
<result>/success.jsp</result>
</action>
//加入 struts2-spring-plugin-2.3.15.3.jar,Struts2 会先从 IOC 容器中获取 Action 的实例