1.å°åºå¦ä½å¨springä¸ä½¿ç¨redis
2.springboot的源码自动装配原理(springboot自动装配原理过程)
å°åºå¦ä½å¨springä¸ä½¿ç¨redis
1. Redis使ç¨åºæ¯
Redisæ¯ä¸ä¸ªå¼æºç使ç¨ANSI Cè¯è¨ç¼åãæ¯æç½ç»ãå¯åºäºå å亦å¯æä¹ åçæ¥å¿åãKey-Valueæ°æ®åºï¼å¹¶æä¾å¤ç§è¯è¨çAPIã
æ们é½ç¥éï¼å¨æ¥å¸¸çåºç¨ä¸ï¼æ°æ®åºç¶é¢æ¯æ容æåºç°çãæ°æ®é太大åé¢ç¹çæ¥è¯¢ï¼ç±äºç£çIOæ§è½çå±éæ§ï¼å¯¼è´é¡¹ç®çæ§è½è¶æ¥è¶ä½ã
è¿æ¶åï¼åºäºå åçç¼åæ¡æ¶ï¼å°±è½è§£å³æ们å¾å¤é®é¢ãä¾å¦Memcacheï¼Redisçãå°ä¸äºé¢ç¹ä½¿ç¨çæ°æ®æ¾å ¥ç¼å读åï¼å¤§å¤§éä½äºæ°æ®åºçè´æ ãæåäºç³»ç»çæ§è½ã
å ¶å®ï¼å¯¹äºhibernateçäºçº§ç¼åï¼æ¯åæ ·çéçãå©ç¨å åé«éç读åé度ï¼æ¥è§£å³ç¡¬ççç¶é¢ã
2. é 置使ç¨redis
é¦å ï¼æ们éè¦å¼å ¥åºæ¬çjarå ãmavenä¸çåºæ¬å¼ç¨å¦ä¸ï¼
ãããã<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.2</version>
</dependency>
ç¶åï¼å¨applicationContextä¸é ç½®å¦ä¸:
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${ redis.maxIdle}" />
<property name="maxTotal" value="${ redis.maxActive}" />
<property name="maxWaitMillis" value="${ redis.maxWait}" />
<property name="testOnBorrow" value="${ redis.testOnBorrow}" />
</bean>
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${ redis.host}" p:port="${ redis.port}" p:password="${ redis.pass}"
p:pool-config-ref="poolConfig" />
<bean id="stringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- å¼å¯äºå¡ï¼å¯ä»¥éè¿transcational注解æ§å¶ -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer" ref="stringSerializer" />
<property name="enableTransactionSupport" value="true" />
</bean>
对äºhibernateçé ç½®å¯ç¥ï¼ç¬¬ä¸ä¸ªpoolconfigæ¯å¯¹è¿æ¥æ± çé ç½®ãå æ¬æ大è¿æ¥æ°ï¼éåæ°ï¼åæ´»æ¶é´ï¼æ大çå¾ æ¶é´ççï¼è¿æä¸äºé¢å¤çé ç½®ï¼è¯·ç´æ¥ç¹å»JedisPoolConfigç±»æºç ï¼è¿è¡æ¥çã
è¿äºé ç½®çææå¦æä¸æç½çè¯ï¼ä¸å®è¦å»æ线ç¨æ± 好好å¦ä¹ ä¸ã
第ä¸ä¸ªé ç½®æ¯è¿æ¥å·¥åï¼é¡¾åæä¹ï¼æåºæ¬ç使ç¨ä¸å®æ¯å¯¹è¿æ¥çæå¼åå ³éãæ们éè¦ä¸ºå ¶é ç½®redisæå¡å¨çè´¦æ·å¯ç ï¼ç«¯å£å·ãï¼è¿éè¿å¯ä»¥é ç½®æ°æ®åºçindexï¼ä½æ¯æ使ç¨æ¶åä¸ç´ä½¿ç¨redisçé»è®¤æ°æ®åºï¼ä¹å°±æ¯ç¬¬0个ï¼
æåä¸ä¸ªé ç½®ç¹å«éè¦ãè¿ä¸ªç±»ä¼¼äºspringæä¾çHibernateDaoSupportã
æ¥ä¸æ¥ï¼å ¨é¨è®²è§£é½å°å´ç»è¿ä¸ªç±»å±å¼ã
3. RedisTemplateç使ç¨
è¿ä¸ªç±»ä½ä¸ºä¸ä¸ªæ¨¡çç±»ï¼æä¾äºå¾å¤å¿«é使ç¨redisçapiï¼èä¸éè¦èªå·±æ¥ç»´æ¤è¿æ¥ï¼äºå¡ã
æåçæ¶åï¼æå建çBaseRedisDaoæ¯ç»§æ¿èªè¿ä¸ªç±»çã继æ¿ç好å¤æ¯æçæ¯ä¸ªDaoä¸ï¼é½å¯ä»¥èªç±çæ§å¶åºååå¨ï¼èªç±çæ§å¶èªå·±æ¯å¦éè¦äºå¡ï¼è¿ä¸ªå ä¸éè¦äºè§£ï¼è·çæç®åçè¿ç§é ç½®æ¹æ³æ¥å³å¯ã
templateæä¾äºä¸ç³»åçoperation,æ¯å¦valueOperation,HashOperation,ListOperation,SetOperationçï¼ç¨æ¥æä½ä¸åæ°æ®ç±»åçRedisã
并ä¸ï¼RedisTemplateè¿æä¾äºå¯¹åºç*OperationsEditorï¼ç¨æ¥éè¿RedisTemplateç´æ¥æ³¨å ¥å¯¹åºçOperationãæ们ææ¶ä¸è®²è¿ä¸ªã
对äºä¸é¢çtest1æ¹æ³ï¼æ们ææ¶ä¸ç¨èèï¼å äºè§£éè¿RedisTemplateæ¥ä½¿ç¨connectionæä½Redisã
Test代ç å¦ä¸ï¼
package cn.test.spjedis;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.cn.redis2.dao.IncrDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class TestRedis {
@Resource(name = "redisTemplate")
private RedisTemplate<String, String> template; // inject the template as ListOperations
//è³äºè¿ä¸ªä¸ºä»ä¹å¯ä»¥æ³¨å ¥ãéè¦åèAbstractBeanFactory doGetBean
//super.setValue(((RedisOperations) value).opsForValue());å°±è¿ä¸è¡ä»£ç ä¾é ä¸ä¸ªeditor
@Resource(name = "redisTemplate")
private ValueOperations<String, Object> vOps;
public void testSet(){
template.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
byte [] key = "tempkey".getBytes();
byte[] value = "tempvalue".getBytes();
connection.set(key, value);
return true;
}
});
}
public void testSet1(){
vOps.set("tempkey", "tempvalue");
}
@Autowired
private IncrDao incr;
@Test
public void addLink() {
System.out.println(incr.incr());
System.out.println(incr.get());
}
}
è¿ä¸ªæ¯å¯¹Stringç±»åæå ¥ç两个æµè¯ãtestæ¹æ³ä¸ï¼ä½¿ç¨äºæ¨¡çç±»æ交åè°(RedisCallBack)çæ¹æ³æ¥ä½¿ç¨jedis connectionæä½æ°æ®ãè¿ä¸é¨åï¼æ没æä¼¼æ¾ç¸è¯å¢ï¼
HibernateTemplateçHibernateCallbackï¼ä»¥åHibernate Sessionç±»ä¸çdoWork以ådoReturningWorkæ¹æ³ï¼é½æ¯ä½¿ç¨äºè¿æ ·çæºå¶ï¼æ¹ä¾¿å¯¹äºè¿æ¥æè sessionçç»ä¸ç®¡çã
public int excuteHqlUpdate(final String hql,final Object ...params){
return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
@Override
@SuppressWarnings("unchecked")
public Integer doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(hql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
queryObject.setParameter(i, params[i]);
}
}
return queryObject.executeUpdate();
}
});
}
springboot的自动装配原理(springboot自动装配原理过程)
springboot自动装配原理面试回答是什么?
SpringBoott自动装配原理主要解决了传统spring的重量级xml配置Bean.实好猜现了自动装配;所以,我们也常在面试中被问到SpringBoot是源码如何实现自动装配。
springboo的源码介绍
SpringBoot基于Spring4.0设计,不仅继承了Spring框架原有的源码优秀特性,而且还通过简化配置来进一步简化了Spring应用的源码整个搭建和开发过程。
另外SpringBoot通过集成大量的源码新蜘蛛侠3资源码框架使得依赖包的版本冲突,以及引用的源码不稳定性等问题得到了很好物绝的解决。?源码SpringBoot框架中还有两个非常重要的策略:开箱即用和约定优于配置,开箱即用,源码Outofbox,源码是源码指在开发过程中。
通过在MAVEN项目的源码pom文件中添加相关依赖包,然后使用对应注解来代替繁琐的源码XML配置文件以管理对象的生命周期。
这个特点使得开发人员摆脱了复杂的源码配置工作以及依赖的管理工作,更加专注于业务逻辑。源码约定优于配置,Conventionoverconfiguration,emui 3.1 源码是一种由SpringBoot本身来配罩袜姿置目标结构。
SpringBoot自动装配原理初看@SpringBootApplication有很多的注解组成,其实归纳就是一个"三体"结构,重要的只有三隐含指个Annotation:
(1)@Configuration注解
(2)@ComponentScan
(3)@EnableAutoConfiguration
从源码中可以知道,最关键的要属@Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的灶配@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。同时借助于Spring框架原有的windgb dump 源码一个工具类:SpringFactoriesLoader,@EnableAutoConfiguration就可以实现智能的自动配置。
总结:@EnableAutoConfiguration作用就是从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(JavaRefletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。这些功能配置类要生效的话,会去classpath中找是否有该类的依赖类(也就是pom.xml必须有对应功能的jar包才行)并且配置类里面注入了默认属性值类,功能类可以引用并赋默认值。生成功能类的rpgmv游戏源码原则是自定义优先,没有自定义时才会使用自动装配类。
1、从spring-boot-autoconfigure.jar/META-INF/spring.factories中获取redis的相关配置类全限定名(有多个的配置类)RedisAutoConfiguration,一般一个功能配置类围绕该功能,负责管理创建多个相关的功能类,比如RedisAutoConfiguration负责:JedisConnectionFactory、RedisTemplate、StringRedisTemplate这3个功能类的弱势抄底源码创建
2、RedisAutoConfiguration配置类生效的一个条件是在classpath路径下有RedisOperations类存在,因此springboot的自动装配机制会会去classpath下去查找对应的class文件。
3.如果pom.xml有对应的jar包,就能匹配到对应依赖class,
4、匹配成功,这个功能配置类才会生效,同时会注入默认的属性配置类@EnableConfigurationProperties(RedisProperties.class)
5.Redis功能配置里面会根据条件生成最终的JedisConnectionFactory、RedisTemplate,并提供了默认的配置形式@ConditionalOnMissingBean(name="redisTemplate")
6.最终创建好的默认装配类,会通过功能配置类里面的@Bean注解,注入到IOC当中
7.用户使用,当用户在配置文件中自定义时候就会覆盖默认的配置@ConditionalOnMissingBean(name="redisTemplate")
1.通过各种注解实现了类与类之间的依赖关系,容器在启动的老斗时候Application.run,会调用EnableAutoConfigurationImportSelector.class的selectImports方法(其实是其父类的方法)--这里需要注意,调用这个方法之前发生了什么和是在哪里调用这个方法需要进一步的探讨
2.selectImports方法最终会调用SpringFactoriesLoader.loadFactoryNames方法来获取一个全面的常用BeanConfiguration列表
3.loadFactoryNames方法会读取FACTORIES_RESOURCE_LOCATION(也就是spring-boot-autoconfigure.jar下面的spring.factories),获取到所有的Spring相关的Bean的全限定名ClassName,大概多个
4.selectImports方法继续调用filter(configurations,autoConfigurationMetadata);这个时候会根据这些BeanConfiguration里面的条件,来一一筛选,最关键的是
@ConditionalOnClass,这个条件注解会去classpath下查找,jar包里面是否有这个条件依赖类,所以必须有了相应的jar包,才有这些依赖类,才会生成IOC环境需要的一些默认配置Bean
5.最后把符合条件的BeanConfiguration注入默认的EnableConfigurationPropertie类里面的属性值,并且注入到IOC环境当中
springboot自动装配原理@EnableAutoConfiguration
1、springboot启动会加载大量的自动配弯弊盯置类:(在下面的spring.factories文件中)
2、通过@ConditionalOnXXX判断我们是否导入了相关的功能(卜键就是pom文件中的starter),如果导入了,就会自动配置。
4、给容器中添加自动配置类的时候,埋和会从XXXProperties类中获取某些属性。我们只需要在配置文件中指定这些属性即可,如果没指定就会用默认值。
XXXA
比如:server.port
最后,通过配置:debug=true
可以查看失效和未生效的类(spring.factories文件中的)