简单来说,就是处理对象的创建、以及对象的依赖关系!
核心理念: IOC inversion of control 控制反转 / DI dependency injection 依赖注入
spring-beans : ioc 实现,配置文件的访问、创建和管理
spring-core: 核心工具包
spring-context:封装IOC容器,提供扩展功能
SpEL : spring的表达式支持
AOP : 面向切面编程支持
Aspects: 对AspectJ框架的支持
instrumentation: 字节码操作
messaging : 对消息服务的支持
transactions : 事务支持
JDBC : spring对JDBC的封装
ORM : spring对于ORM框架的支持
控制权从调用的类转换到Spring容器,由Spring来实例化对象及依赖注入
//声明一个普通bean
<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
//ref 注入已有的bean
<property name="userDao" ref="userDao"/>
//value 注入基本类型
<property name="age" value="20"/>
//注入list
<property name="list">
<list>
<value>1value>
<value>2value>
<value>3value>
<value>4value>
list>
property>
//注入map
<property name="map">
<map>
<entry key="pig" value="pick">entry>
<entry key="dog" value="yellow">entry>
<entry key="cat" value="black">entry>
map>
property>
bean>
beans>
//默认构造器实例化
<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
//静态工厂方法实例化
<bean id="connection" factory-method="getConnection" class="com.woniuxy.spring.common.JDBCUtils"/>
//工厂bean实例化
<bean id="holidayFactory" class="com.woniuxy.spring.factory.HolidayFactory"/>
<bean id="holiday" factory-bean="holidayFactory" factory-method="create">bean>
一个类实现FactoryBean接口,实现其方法
配置之后,bean的实例为FactoryBean#getObject方法的返回值
java类:
public class CarFactory implements FactoryBean<Car> {
@Override
public Car getObject() throws Exception {
return new Car();
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
}
xml配置:
<bean id="car" class="com.woniuxy.spring.factory.CarFactory"/>
setter注入:
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
<property name="userDao" ref="userDao"/>
bean>
public class UserServiceImp implements UserService {
//属性
private UserDaoImp tdi;
//setter注入
public void setTdi(UserDaoImp tdi) {
this.tdi = tdi;
}
}
构造器注入:
<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
<constructor-arg name="tdi" ref="userDao"/>
<constructor-arg index="1" value="20"/>
bean>
public class UserServiceImp implements UserService {
//属性
private UserDaoImp tdi;
private String age;
//构造器注入
public UserServiceImp(UserDaoImp tdi,String age){
this.tdi = tdi;
this.age = age;
}
}
<bean id="userDao" class="com.woniuxy.spring.dao.daoimp.UserDaoImp"/>
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp">
<constructor-arg name="tdi" ref="userDao"/>
<constructor-arg index="1" value="20"/>
bean>
prototype 原型 => 每次创建一个实例
[*]singleton 单例 => 一个bean的定义,只有一个实例,不是一个类只有一个实例(默认为单例)
request 一个请求一个实例
session 一个会话一个实例
websocket 一次websocket链接一个实例
1.在bean配置上写init-method和destroy-method
2.实现InitializingBean和DisposableBean及其方法
public class Cycle2 implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("开始....");
}
@Override
public void destroy() throws Exception {
System.out.println("结束了....");
}
}
解耦合,类与类之间的耦合度降低;
提升代码的灵活性,可维护性
注解
注册springbean @Controller
@Service
@Repository
@Component
自动依赖注入 @Autowired
@Value
生命周期 @PostConstruct
@PreDestroy
作用域范围 @Scope
xml配置
<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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.woniuxy.spring"/>
beans>
注解: @Bean
@Configuration
@ComponentScan
@Configuration
标记一个类为配置类
@Bean
标记某个方法返回值为spring的bean,方法参数为依赖注入的请求
扫描
@Configuration
标记一个类为配置类 applicationContext.xml
@ComponentScan
打开包扫描功能,并且指定扫描的包 等价于
加入@Controller...@Autowired
@PropertySource("{配置文件位置}")
java配置
@Configuration
@ComponentScan("com.woniuxy.spring")
@PropertySource("database.properties")
public class AppConfig {
//获取配置文件database.properties里的信息
@Value("${forname}")
private String forname;
@Value("${url}")
private String url;
@Value("${user}")
private String user;
@Value("${password}")
private String password;
//配置Bean
@Bean
public UserDaoImp userDaoImp(){
return new UserDaoImp();
}
@Bean
public UserServiceImp userServiceImp(){
return new UserServiceImp();
}
//结束时调用关闭的方法
@Bean(destroyMethod = "close")
public DruidDataSource druidDataSource(){
DruidDataSource dds = new DruidDataSource();
dds.setDriverClassName(forname);
dds.setUrl(url);
dds.setUsername(user);
dds.setPassword(password);
return dds;
}
}
public static void main(String[] args) throws SQLException {
//读取java配置
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
//读取Bean,获得实体类
UserServiceImp usi = ac.getBean("userServiceImp",UserServiceImp.class);
}
AOP Aspect Oritented Programming 面向切面编程
连接点 JoinPoint 需要加入功能的位置,方法
切入点 PointCut 真正执行加入功能的连接点
通知 Advice 需要实现的功能,实现MethodBeforeAdivce
接口
前置通知 : 方法执行之前 MethodBeforeAdvice
后置通知 : 方法执行之后 AfterReturningAdvice
环绕通知 : 方法执行前后 MethodInterceptor
异常通知 : 抛出异常时
最终通知 : finally
切面 Aspect Java语言中,将切入点和通知等组装在一起的代码单元
目标对象 Target 要操作的对象
织入 Weave 将功能加入到切入点中的过程
事务 : 一批同时成功或失败的DML
打印日志、性能监控、事务管理、安全验证,每一个类的每一个public方法的参数都打印出来…
1.配置service
2.配置通知
3.配置切入点,class= org.springframework.aop.support.JdkRegexpMethodPointcut 4.配置属性pattern=> service的方法
5.配置切面,class=org.springframework.aop.support.DefaultPointcutAdvisor 连接切入点和通知
6.包装service类, class= org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
7.获取bean,调用方法,将会看到通知执行了
<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.woniuxy.spring.service.serviceimp.UserServiceImp"/>
<bean id="beforeExecution" class="com.woniuxy.spring.component.Before"/>
<bean id="pointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value="com.woniuxy.spring.service.serviceimp.UserServiceImp.addUser"/>
bean>
<bean id="aspect" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="pointCut"/>
<property name="advice" ref="test"/>
bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
bean>
<bean id="test" class="com.woniuxy.spring.component.Test"/>
beans>
xml配置
<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"
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">
<bean id="userService" class="com.woniuxy.spring.service.serviceimp.UserServiceImp"/>
<bean id="txAdvice" class="com.woniuxy.spring.component.Test1"/>
<aop:config>
<aop:aspect ref="txAdvice">
<aop:pointcut id="servicePointcut" expression="execution(* com.woniuxy.spring.service.serviceimp.UserServiceImp.*(..))"/>
<aop:before method="begin" pointcut-ref="servicePointcut"/>
<aop:after-returning method="commit" pointcut-ref="servicePointcut"/>
<aop:after-throwing method="rollback" pointcut-ref="servicePointcut"/>
aop:aspect>
aop:config>
beans>
java注解
@Configuration
@ComponentScan("com.woniuxy.spring")
@EnableAspectJAutoProxy
public class TXconfig {
}
@Component
@Aspect
public class TXApsect {
@Pointcut("execution(* com.woniuxy.spring.service.serviceimp.UserServiceImp.*(..))")
public void servicePointcut(){}
@Around("servicePointcut()")
public Object invoke(ProceedingJoinPoint pjp) {
Object[] args = pjp.getArgs();
Object result = null;
try {
System.out.println("开启事务");
result = pjp.proceed(args);
System.out.println("提交事务");
}catch (Throwable t){
t.printStackTrace();
System.out.println("回滚事务");
}
return result;
}
}
1.代理类和被代理类必须有相同的接口
2.代理类持有了被代理类对象
一个有趣的代理模式代码:
接口
public interface Invest {
double invoke(double money);
}
Boss类
public class Boss implements Invest{
public double invoke(double money) {
System.out.println("老板:"+money+"万,已经打在卡上了,你看到没有");
return money;
}
}
Proxy类
public class Proxy implements Invest{
Boss boss = new Boss();
public Proxy(Boss boss){
this.boss = boss;
}
public double invoke(double money) {
double newMoney = money *1.2;
System.out.println("代理:客户需要"+money+"万,我给老板说需要"+newMoney+"万,自己扣下"+(money*0.2)+"万");
double bossMoney = boss.invoke(newMoney);
return money;
}
}
Subject类
public class Subject {
public static void main(String[] args) {
Boss boss = new Boss();
Invest in = new Proxy(boss);
System.out.println("客户:我需要1000.0万");
double money = in.invoke(1000);
System.out.println("客户:已经收到了"+money+"万");
}
}