Spring框架
Spring框架是个轻量级的java EE框架。所谓轻量级,是指不依赖于容器就能运行。Spring以IOC,AOP为主要思想,能够协同Struts,Hibernate,WebWork,JSF,iBatis等众多框架
Spring解决的主要问题
1 Spring的IOC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。提升了代码的灵活性,可维护性高
2 Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。
3 Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
4 Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。
IOC
IOC概念
Spring最重要思想之一IOC(Inversion of Control控制反转),或者称为DI(Dependency Injection,依赖注入)。就是将我们需要的对象实例化之后交给Spring来统一管理,哪些地方需要就对哪里依赖注入
IOC的优势
实现组件之间的解耦,就是降低了类与类之间的耦合度。提高程序的灵活性和可维护性
IOC实例化的方式
1 无参构造方法
这种方式需要系统默认的无参构造,声明的对象也要有setter方法
<!-- 在xml中 无参构造方法-->
<bean id="userdao" class="com.woniuxy.dao.Userdao"></bean>
<bean id="userservice" class="com.woniuxy.service.Userservice">
<!-- 在下面进行依赖的注入-->
<property name="userdao" ref="userdao"></property>
</bean>
<bean id="controller" class="com.woniuxy.controller.Controller">
<property name="userservice" ref="userservice"/>
</bean>
2 静态工厂方法
这种方法必须类中的方法为静态方法,我们通过调用这个方法,返回的实例化就可以直接赋给id,不是clas的实例,而是方法返回的实例
<!--在xml中 静态工厂方法创建-->
<bean id="userFactory" factory-method="getM" class="com.woniuxy.controller.FactorMathod" ></bean>
3 实例工厂方法
这种方法需要先有一个bean的实例,然后通过调用这个bean的方法返回一个新的实例,来作为这个bean的实例
<!--在xml中 工厂bean实例化-->
<bean id="factoryMethod" class="com.woniuxy.controller.FactorMathod"></bean>
<bean id="getuser" factory-bean="factoryMethod" factory-method="getU"></bean>
4 实现FactoryBean接口方法
需要先实现FactoryBean接口,然后重写方法,在object方法中返回对象,来作为这个bean的实例
java代码
public class TestInterface implements FactoryBean<Userdao> {
@Override
public Userdao getObject() throws Exception {
return new Userdao();
}
@Override
public Class<?> getObjectType() {
return Userdao.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
下面是xml
<!--在xml中 Spring的FactoryBean接口实例化-->
<bean id="getInterface" class="com.woniuxy.controller.TestInterface"></bean>
IOC的依赖注入方式
1 构造方法的方式注入
<bean id="car" class="cn.itcast.spring.demo4.Car">
<constructor-arg name="name" value="保时捷"/>
<constructor-arg name="price" value="1000000"/>
<bean>
2 set 方法的方式注入
<bean id="car2" class="cn.itcast.spring.demo4.Car2">
<property name="name" value="奇瑞 QQ"/>
<property name="price" value="40000"/>
<bean>
Bean的生命周期
(1)、xml中指定初始化(init-method)和销毁(destory-method)的方法
<bean id="person" class="domain.Person" init-method="" destroy-method="">
(2)、实现initiializingBean接口,初始化。实现disposableBean接口,销毁
Bean的作用域
- 默认情况下,bean的作用域是单例的(singleton),也就是spring的应用上下文中只能有一个bean实例,创建一次。
- 原型(prototype),每次注入或者通过spring容器获取bean的时候都会重新创建一个bean实例。
- 会话(session),web应用中,针对每个会话创建一个bean实例。
- 请求(request),web应用中,针对每个请求创建一个bean实例
- 链接(websocket) ,web应用中,针对每个链接创建一个bean实例
IOC的三种配置方法
在这之前需要导入Spring context的jar包,以及一些自己需要的包
1 XML配置
主要是将bean信息配置到xml文件中,让Spring对配置的类进行实例,然后放入容器中,最后再进行依赖注入
首先在resources文件中创建一个applicationconfig.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="userdao" class="com.woniuxy.dao.Userdao"></bean>
<bean id="userservice" class="com.woniuxy.service.Userservice">
<!-- 在下面进行依赖的注入-->
<!-- 注意 这种方法需要java类中有setter方法,name为变量名 --!>
<property name="userdao" ref="userdao"></property>
</bean>
<bean id="controller" class="com.woniuxy.controller.Controller">
<property name="userservice" ref="userservice"/>
</bean>
<!-- 静态工厂方法创建,这个必须要java方法为静态方法-->
<bean id="userFactory" factory-method="getM" class="com.woniuxy.controller.FactorMathod" ></bean>
<!-- 工厂bean实例化,需要方法有具体返回-->
<bean id="factoryMethod" class="com.woniuxy.controller.FactorMathod"></bean>
<bean id="getuser" factory-bean="factoryMethod" factory-method="getU"></bean>
<!-- Spring的FactoryBean接口实例化,java类要实现FactoryBean接口,重写方法,并在object方法中返回实例作为这个bean的实例-->
<bean id="getInterface" class="com.woniuxy.controller.TestInterface"></bean>
<!-- 构造器注入-->
<bean id="person" class="com.woniuxy.controller.Person">
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" value="20"/>
<constructor-arg index="2">
<list>
<value>11111</value>
<value>12222</value>
<value>13333</value>
<value>14444</value>
</list>
</constructor-arg>
</bean>
</beans>
xml配置文件中我们通过property对依赖进行了注入,这种方法需要类中有setter方法才可以,并且类中已经声明了该对象,
也可以通过java代码读取配置文件来调用他的bean方法,最后获取一个实例
//通过读取方式获得
ClassPathXmlApplicationContext cc = new ClassPathXmlApplicationContext("applicationContext.xml");
//然后就可以通过他的getBean方法获取我们需要的实例了
Controller controller = cc.getBean("controller", Controller.class);
上面这种java中直接获取getBean方法中,第一个参数为id名,第二个参数为类的实例,如果不写则返回object对象
2 注解声明配置
下面说一种代码量比较少的方式,使用注解来实现
同样先在resources文件下创建一个 applicationcofig.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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 下面就是让spring对base-package中的包路径进行扫描,他们根据注解来辨别我们的需求,自动加入依赖 --!>
<context:component-scan base-package="com.woniuxu.spring"/>
</beans>
有了上面的配置信息之后,我们就可以在需要的类上面加入注解对其进行实例化了
@Controller 是加在controlle层中的类上面的
@Service 是加在service层 中的类上面的
@Repository 是加在dao层的类上面的
@Component 其他注解,不在上面这个三个中的注解,加上之后也会进行读取,具体用法下面会说到
@Autowired 自动注入依赖,加在声明的对象上面即可
@Scope(“作用域”) 里面填写作用域,可以进行修改
@PostConstruct 加在方法上面,为生命周期的开始
@RreDestroy 加在方法上面,为生命周期的结束
下面给出一个简单的类注解方式
@Repository
public class UserDao {
@Autowired
private QueryRunner qr ;
public User getUser(String username, String password) {
try {
return qr.query("select * from user where username = ? and password = ? ", new BeanHandler<User>(User.class), username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return null ;
}
}
由于我写的这个类是dao层的所以加了@Repository,其他根据具体使用相应注解在这里插入代码片
3 JavaConfig声明配置
下面介绍一种纯java代码实现方法
这儿我们就不需要创建xml文件了,而是用java的类来替代了
1 首先创建一个用来配置的java类,然后在类上面加入@Configuration注解,代表这个类为我们的配置类
2 然后写方法,方法的名字就相当于我们xml中配置的bean的id名,方法上面一定要加入@Bean注解,这样才能表示为一个bean
3 同样的也需要对我们的每个层加入对应的注解,需要的实例任然要有setter方法
@Controller 是加在controlle层中的类上面的
@Service 是加在service层 中的类上面的
@Repository 是加在dao层的类上面的
@Component 其他注解,不在上面这个三个中的注解,加上之后也会进行读取,具体用法下面会说到
@Autowired 自动注入依赖,加在声明的对象上面即可
下面给出一个例子
@Configuration
public class Appconfig {
@Bean
public Controllers1 controller(UserService userService){
Controllers1 controllers1 = new Controllers1();
controllers1.setUserService(userService);
return controllers1 ;
}
@Bean
public UserService userService(UserDao userDao){
UserService userService = new UserService();
userService.setUserDao(userDao);
return userService ;
}
@Bean
public UserDao userDao(QueryRunner qr){
UserDao userDao = new UserDao();
userDao.setQr(qr);
return userDao ;
}
}
如果觉得上面的方法太麻烦也可以这样
在这个类上面加上@ComponentScan(“包路径”) 让他对这个包路径进行扫描来自动实例化我们需要的对象,这样就不需要setter方法,也不需要写bean方法了
@Configuration
@ComponentScan("com.woniuxu.spring")
public class Appconfig {
}
以上就是IOC三种配置方法了
AOP
AOP的概念
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP应用场景
AOP用来封装横切关注点,具体可以在下面的场景中使用
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
AOP配置方式
1 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">
<!-- 配置service-->
<bean id="service" class="com.woniuxy.aop.service.UserService"></bean>
<!-- 配置通知-->
<bean id="aopconfig" class="com.woniuxy.aop.AOPConfig"></bean>
<!-- 配置切入点-->
<bean id="aspect" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value="com.woniuxy.aop.service.UserService.addUser"></property>
</bean>
<!-- 配置切面-->
<bean id="cutpoint" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="aspect"></property>
<property name="advice" ref="aopconfig"></property>
</bean>
<!-- 包装service类-->
<bean id="creator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
</beans>
这种配置方式使用bean,配置过程比较复杂,代码量较多,下面给出一种稍微简化的
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="userDao" class="com.woniuxy.aop.dao.impl.UserDaoImpl"></bean>
<bean id="txAOP" class="com.woniuxy.aop.TransactionAOP"></bean>
<!-- 切面-->
<aop:config>
<aop:aspect ref="txAOP">
<!-- 扫包-->
<aop:pointcut id="daoPointcut" expression="execution(* com.woniuxy.aop.dao.impl.*.*(..))"/>
<aop:before method="TxStart" pointcut-ref="daoPointcut"/>
<aop:after-returning method="TxCommit" pointcut-ref="daoPointcut"/>
<aop:after-throwing method="TxRollBack" pointcut-ref="daoPointcut"/>
</aop:aspect>
</aop:config>
<context:component-scan base-package="com.woniuxy.aop"/>
<aop:aspectj-autoproxy/>
</beans>
2 注解方式
@Component
@Aspect
public class Txconfig {
@Pointcut("execution(* com.woniuxy.aop.dao.impl.*.*(..))")
public void pointecut(){
}
@Around("pointecut()")
public Object around(ProceedingJoinPoint pj) {
System.out.println("开启事物");
Object[] args = pj.getArgs();
Object proceed = null ;
try {
proceed = pj.proceed(args);
System.out.println("提交事物");
} catch (Throwable throwable) {
System.out.println("回滚事物");
}
return proceed ;
}
}
上面的代码是根据对应方法加上注解,还需在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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 下面就是让spring对base-package中的包路径进行扫描,他们根据注解来辨别我们的需求,自动加入依赖 --!>
<context:component-scan base-package="com.woniuxu.spring"/>
</beans>
这样才可以做到自动扫包
3 java配置方式
顾名思义就是不使用xml全部统一使用java代码表写,配置每个层和前面提到的IOC里面的注解一样,
@Component
@Aspect
public class Txconfig {
@Pointcut("execution(* com.woniuxy.aop.dao.impl.*.*(..))")
public void pointecut(){
}
@Around("pointecut()")
public Object around(ProceedingJoinPoint pj) {
System.out.println("开启事物");
Object[] args = pj.getArgs();
Object proceed = null ;
try {
proceed = pj.proceed(args);
System.out.println("提交事物");
} catch (Throwable throwable) {
System.out.println("回滚事物");
}
return proceed ;
}
}
这里是我们要环绕的类,@Around ,然后需要配置一个自动扫包的的配置类
@Configuration
@ComponentScan("com.woniuxy.aop")
@EnableAspectJAutoProxy
public class AutoWirted {
}
这个类就比较简单了,这要是
@Configuration说明这个配置类
@ComponentScan(“com.woniuxy.aop”)给出我们需要扫包的路径
@EnableAspectJAutoProxy启动
这样就完成了一个纯java的配置了