Spring常用注解

Spring常用注解

使用注解来构造IoC容器

用注解来向Spring容器注册Bean。需要在applicationContext.xml中注册<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>

如:在base-package指明一个包

1 <context:component-scan base-package="cn.gacl.java"/>

表明cn.gacl.java包及其子包中,如果某个类的头上带有特定的注解【@Component/@Repository/@Service/@Controller】,就会将这个对象作为Bean注册进Spring容器。也可以在<context:component-scan base-package=” ”/>中指定多个包,如:

1 <context:component-scan base-package="cn.gacl.dao.impl,cn.gacl.service.impl,cn.gacl.action"/>

多个包逗号隔开。

1、@Component

@Component
是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,@Component不推荐使用。

2、@Controller

@Controller对应表现层的Bean,也就是Action,例如:

1 @Controller 2 @Scope("prototype") 3 public class UserAction extends BaseAction<User>{ 4 …… 5 }

使用@Controller注解标识UserAction之后,就表示要把UserAction交给Spring容器管理,在Spring容器中会存在一个名字为”userAction”的action,这个名字是根据UserAction类名来取的。注意:如果@Controller不指定其value【@Controller】,则默认的bean名字为这个类的类名首字母小写,如果指定value【@Controller(value=”UserAction”)】或者【@Controller(“UserAction”)】,则使用value作为bean的名字

这里的UserAction还使用了@Scope注解,@Scope(“prototype”)表示将Action的范围声明为原型,可以利用容器的scope=”prototype”来保证每一个请求有一个单独的Action来处理,避免struts中Action的线程安全问题。spring 默认scope 是单例模式(scope=”singleton”),这样只会创建一个Action对象,每次访问都是同一Action对象,数据不安全,struts2 是要求每次次访问都对应不同的Action,scope=”prototype” 可以保证当有请求的时候都创建一个Action对象

3、@ Service

@Service对应的是业务层Bean,例如:

1 @Service("userService") 2 public class UserServiceImpl implements UserService { 3 ……… 4 }

@Service(“userService”)注解是告诉Spring,当Spring要创建UserServiceImpl的的实例时,bean的名字必须叫做”userService”,这样当Action需要使用UserServiceImpl的的实例时,就可以由Spring创建好的”userService”,然后注入给Action:在Action只需要声明一个名字叫“userService”的变量来接收由Spring注入的”userService”即可,具体代码如下:

1 // 注入userService
2 @Resource(name = "userService") 3 private UserService userService;

注意:在Action声明的“userService”变量的类型必须是“UserServiceImpl”或者是其父类“UserService”,否则由于类型不一致而无法注入,由于Action中的声明的“userService”变量使用了@Resource注解去标注,并且指明了其name = “userService”,这就等于告诉Spring,说我Action要实例化一个“userService”,你Spring快点帮我实例化好,然后给我,当Spring看到userService变量上的@Resource的注解时,根据其指明的name属性可以知道,Action中需要用到一个UserServiceImpl的实例,此时Spring就会把自己创建好的名字叫做”userService”的UserServiceImpl的实例注入给Action中的“userService”变量,帮助Action完成userService的实例化,这样在Action中就不用通过“UserService userService = new UserServiceImpl();”这种最原始的方式去实例化userService了。如果没有Spring,那么当Action需要使用UserServiceImpl时,必须通过“UserService userService = new UserServiceImpl();”主动去创建实例对象,但使用了Spring之后,Action要使用UserServiceImpl时,就不用主动去创建UserServiceImpl的实例了,创建UserServiceImpl实例已经交给Spring来做了,Spring把创建好的UserServiceImpl实例给Action,Action拿到就可以直接用了。Action由原来的主动创建UserServiceImpl实例后就可以马上使用,变成了被动等待由Spring创建好UserServiceImpl实例之后再注入给Action,Action才能够使用。这说明Action对“UserServiceImpl”类的“控制权”已经被“反转”了,原来主动权在自己手上,自己要使用“UserServiceImpl”类的实例,自己主动去new一个出来马上就可以使用了,但现在自己不能主动去new“UserServiceImpl”类的实例,new“UserServiceImpl”类的实例的权力已经被Spring拿走了,只有Spring才能够new“UserServiceImpl”类的实例,而Action只能等Spring创建好“UserServiceImpl”类的实例后,再“恳求”Spring把创建好的“UserServiceImpl”类的实例给他,这样他才能够使用“UserServiceImpl”,这就是Spring核心思想“控制反转”,也叫“依赖注入”,“依赖注入”也很好理解,Action需要使用UserServiceImpl干活,那么就是对UserServiceImpl产生了依赖,Spring把Acion需要依赖的UserServiceImpl注入(也就是“给”)给Action,这就是所谓的“依赖注入”。对Action而言,Action依赖什么东西,就请求Spring注入给他,对Spring而言,Action需要什么,Spring就主动注入给他。

4、@ Repository

@Repository对应数据访问层Bean ,例如:

1 @Repository(value="userDao") 2 public class UserDaoImpl extends BaseDaoImpl<User> { 3 ……… 4 }

@Repository(value=”userDao”)注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。

当Service需要使用Spring创建的名字叫“userDao”的UserDaoImpl实例时,就可以使用@Resource(name = “userDao”)注解告诉Spring,Spring把创建好的userDao注入给Service即可。

1 // 注入userDao,从数据库中根据用户Id取出指定用户时需要用到
2 @Resource(name = "userDao") 3 private BaseDao<User> userDao;

 

注解实现Bean配置主要用来进行如依赖注入、生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的数据将覆盖基于注解配置中的依赖注入的数据
注册注解处理器

 方式一:bean

[html] 
view plain
copy

  1. <bean class=“org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor”/>  

 方式二: 命名空间<context:annotation-config />

<context:annotationconfig /> 将隐式地向Spring 容器注册AutowiredAnnotationBeanPostProcessor 、CommonAnnotationBeanPostProcessor 、 PersistenceAnnotationBeanPostProcessor 以及RequiredAnnotationBeanPostProcessor 这4 个BeanPostProcessor 。

 方式三: 命名空间<context:component-scan />

如果要使注解工作,则必须配置component-scan ,实际上不需要再配置annotation-config。

[html] 
view plain
copy

  1. <context:component-scan base-package=“com.spring.ioc5”>  
  2.         <!– annotation 通过注解来过滤          org.example.SomeAnnotation    
  3.              assignable 通过指定名称过滤        org.example.SomeClass  
  4.              regex      通过正则表达式过滤      org\.example\.Default.*  
  5.              aspectj    通过aspectj表达式过滤  org.example..*Service+  
  6.          —>  
  7.         <context:include-filter type=“regex” expression=“com.spring.ioc5.*”/>  
  8.         <context:exclude-filter type=“annotation” expression=“org.springframework.beans.factory.annotation.Autowired”/>  
  9. </context:component-scan>  

 

• Spring 支持以下4 种类型的过滤方式:

     • 注解 org.example.SomeAnnotation 将所有使用SomeAnnotation 注解的类过滤出来

     • 类名指定 org.example.SomeClass 过滤指定的类

     • 正则表达式 com.kedacom.spring.annotation.web..* 通过正则表达式过滤一些类

     • AspectJ 表达式 org.example..*Service+ 通过AspectJ 表达式过滤一些类

Spring3的基于注解实现Bean依赖注入支持如下三种注解:

  • Spring自带依赖注入注解: Spring自带的一套依赖注入注解;
  • JSR-250注解:Java平台的公共注解,是Java EE 5规范之一,在JDK6中默认包含这些注解,从Spring2.5开始支持。
  • JSR-330注解:Java 依赖注入标准,Java EE 6规范之一,可能在加入到未来JDK版本,从Spring3开始支持;
  • JPA注解:用于注入持久化上下文和尸体管理器。

@Required

         • 例如 

[java] 
view plain
copy

  1. @required                
  2. public  setName(String name){}  

              
@
 required 负责检查一个
bean在初始化时其声明的
 set方法是否被执行, 当某个被标注了 @Required 的 Setter 方法没有被调用,则 Spring 在解析的时候会抛出异常,以提醒开发者对相应属性进行设置。 @Required 注解只能标注在 Setter 方法之上。因为依赖注入的本质是检查 Setter 方法是否被调用了,而不是真的去检查属性是否赋值了以及赋了什么样的值。如果将该注解标注在非 setXxxx() 类型的方法则被忽略。

@Autowired 采用byType的方式 

[java] 
view plain
copy

  1. @Autowired  
  2. private ISoftPMService softPMService;  

[java] 
view plain
copy

  1. @Autowired(required=false)  
  2.     构造器、字段、方法  

       @Autowired 根据bean 类型从spring 上线文中进行查找,注册类型必须唯一,否则报异常。与@Resource 的区别在于,@Resource 允许通过bean 名称或bean 类型两种方式进行查找@Autowired(required=false) 表示,如果spring 上下文中没有找到该类型的bean 时, 才会使用new SoftPMServiceImpl();
       @Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key。
       @Autowired 还有一个作用就是,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。

@Qualifier 和@AutoWired联合使用,自动装配的策略就变成byName

  使用@Autowired 时,如果找到多个同一类型的bean,则会抛异常,此时可以使用 @Qualifier(“beanName”),明确指定bean的名称进行注入,此时与 @Resource指定name属性作用相同。

[java] 
view plain
copy

  1. @Qualifier(value = “限定标识符”)     
  2. 字段、方法、参数    


(1)根据基于XML配置中的<qualifier>标签指定的名字进行注入,使用如下方式指定名称 

[java] 
view plain
copy

  1. <qualifier  type=“org.springframework.beans.factory.annotation.Qualifier”  value=“限定标识符”/>    

其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的。

[java] 
view plain
copy

  1. @Autowired    
  2.    //根据<qualifier>标签指定Bean限定标识符    
  3.    public void initDataSource(@Qualifier(“mysqlDataSource”) DataSource dataSource) {    
  4.        this.dataSource = dataSource;    
  5.    }    

使用@Qualifier(“mysqlDataSource”)来指定候选Bean的限定标识符,我们需要在配置文件中使用<qualifier>标签来指定候选Bean的限定标识符“mysqlDataSource”:

  1. <bean id=“mysqlDataSourceBean” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>   
  2.      <qualifier value=“mysqlDataSource”/>   
  3. </bean>  


(2)缺省的根据Bean名字注入
:最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,但如果你指定了<qualifier>标签将不会发生容错。

  1.     @Autowired  
  2.     @Qualifier(value = “mysqlDataSource2”//指定Bean限定标识符   
  3.     //@Qualifier(value = “mysqlDataSourceBean”)   
  4.     //是错误的注入,不会发生回退容错,因为你指定了<qualifier>   
  5.     public void initDataSource(DataSource dataSource) {   
  6.         this.dataSource = dataSource;   
  7.     }   

(3)扩展@Qualifier限定描述符注解:
对@Qualifier的扩展来提供细粒度选择候选者;


如果我们有两个数据源,分别为Mysql和Oracle,因此注入两者相关资源时就牵扯到数据库相关,如在DAO层注入SessionFactory时,当然可以采用前边介绍的方式,但为了简单和直观我们希望采用自定义注解方式。

1. 扩展@Qualifier限定描述符注解来分别表示Mysql和Oracle数据源

  1. /** 表示注入Mysql相关 */  
  2. @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})   
  3. @Retention(RetentionPolicy.RUNTIME)   
  4. @Qualifier  
  5. public @interface Mysql {   
  6. }  

  1. /** 表示注入Oracle相关 */  
  2. @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})   
  3. @Retention(RetentionPolicy.RUNTIME)   
  4. @Qualifier  
  5. public @interface Oracle {   
  6. }  

  1. @Autowired  
  2.     public void initDataSource(@Mysql DataSource mysqlDataSource, @Oracle DataSource oracleDataSource) {   
  3.         this.mysqlDataSource = mysqlDataSource;   
  4.         this.oracleDataSource = oracleDataSource;   
  5.     }   

  1. <bean id=“mysqlDataSourceBean” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>   
  2.      <qualifier value=“mysqlDataSource”/>   
  3.      <qualifier type=“cn.javass.spring.chapter12.qualifier.Mysql”/>   
  4. </bean>   
  5. <bean id=“oracleDataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>   
  6.       <qualifier type=“cn.javass.spring.chapter12.qualifier.Oracle”/>   
  7. </bean>
     
  1.  Assert.assertEquals(ctx.getBean(“mysqlDataSourceBean”), testBean33.getMysqlDataSoruce());  
  2.  Assert.assertEquals(ctx.getBean(“oracleDataSource”), testBean33.getOracleDataSoruce());  

测试通过

2.扩展参数的注解

  1. package cn.javass.spring.chapter12.qualifier;   
  2. public enum DataBase {   
  3.     ORACLE, MYSQL;   
  4. }  

  1. @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})   
  2. @Retention(RetentionPolicy.RUNTIME)   
  3. @Qualifier  
  4. public @interface DataSourceType {   
  5.     String ip();      //指定ip,用于多数据源情况   
  6.     DataBase database();//指定数据库类型   
  7. }  

  1. @Autowired  
  2.     public void initDataSource(   
  3.             @DataSourceType(ip=“localhost”, database=DataBase.MYSQL)   
  4.             DataSource mysqlDataSource,   
  5.             @DataSourceType(ip=“localhost”, database=DataBase.ORACLE)   
  6.             DataSource oracleDataSource) {   
  7.         this.mysqlDataSource = mysqlDataSource;   
  8.         this.oracleDataSource = oracleDataSource;   
  9.     }   

  1. <bean id=“mysqlDataSourceBean” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>   
  2.     <qualifier value=“mysqlDataSource”/>   
  3.     <qualifier type=“cn.javass.spring.chapter12.qualifier.Mysql”/>   
  4.     <qualifier type=“cn.javass.spring.chapter12.qualifier.DataSourceType”>   
  5.         <attribute key=“ip” value=“localhost”/>   
  6.         <attribute key=“database” value=“MYSQL”/>   
  7.     </qualifier>   
  8. </bean>   
  9. <bean id=“oracleDataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>   
  10.     <qualifier type=“cn.javass.spring.chapter12.qualifier.Oracle”/>   
  11.     <qualifier type=“cn.javass.spring.chapter12.qualifier.DataSourceType”>   
  12.         <attribute key=“ip” value=“localhost”/>   
  13.         <attribute key=“database” value=“ORACLE”/>   
  14.     </qualifier>   
  15. </bean>  

  1. Assert.assertEquals(ctx.getBean(“mysqlDataSourceBean”), testBean34.getMysqlDataSource());   
  2. Assert.assertEquals(ctx.getBean(“oracleDataSource”), testBean34.getOracleDataSoruce());   

测试通过

3. 自定义注解限定描述符:
完全不使用@Qualifier,而是自己定义一个独立的限定注解;

  1. @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})   
  2. @Retention(RetentionPolicy.RUNTIME)   
  3. public @interface CustomQualifier {   
  4.     String value();   
  5. }  

  1. @Autowired  
  2.     public TestBean35(@CustomQualifier(“oracleDataSource”) DataSource dataSource) {   
  3.         this.dataSoruce = dataSource;   
  4.     } 

在Spring配置文件中注册CustomQualifier自定义注解限定描述符,只有注册了Spring才能识别:

  1. <bean id=“customAutowireConfigurer” class=“org.springframework.beans.factory.annotation.CustomAutowireConfigurer”>   
  2.     <property name=“customQualifierTypes”>   
  3.         <set>   
  4.             <value>cn.javass.spring.chapter12.qualifier.CustomQualifier</value>   
  5.         </set>   
  6.    </property>   
  7. </bean>  


@Value

用于注入SpEL表达式,可以放置在字段方法或参数上

[java] 
view plain
copy

  1. @Value(value = “SpEL表达式”)     
  2. 字段、方法、参数  

1、可以在类字段上使用该注解:

  1. @Value(value = “#{message}”)   
  2. private String message;  

2、可以放置在带@Autowired注解的方法的参数上

  1. @Autowired  
  2. public void initMessage(@Value(value = “#{message}#{message}”) String message) {   
  3.     this.message = message;   
  4. }  

3、还可以放置在带@Autowired注解的构造器的参数上:

  1. @Autowired  
  2. private TestBean43(@Value(value = “#{message}#{message}”) String message) {   
  3.     this.message = message;   
  4. }  


@Lazy
定义Bean将延迟初始化

  1. @Component(“component”)   
  2. @Lazy(true)   
  3. public class TestCompoment {   
  4. ……   
  5. } 


@DependsOn

定义Bean初始化及销毁时的顺序

  1. @Component(“component”)   
  2. @DependsOn({
    “managedBean”})   
  3. public class TestCompoment {   
  4. ……   
  5. }  


@Scope

定义Bean作用域,默认单例

  1. @Component(“component”)   
  2. @Scope(“singleton”)   
  3. public class TestCompoment {   
  4. ……   


@Primary


自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常

  1. @Component(“component”)   
  2. @Primary  
  3. public class TestCompoment {   
  4. ……   


@Configuration


注解需要作为配置的类,表示该类将定义Bean配置元数据,
@Configuration注解的类本身也是一个Bean,因为@Configuration被@Component注解了,因此@Configuration注解可以指定value属性值,如“ctxConfig”就是该Bean的名字,如使用“ctx.getBean(“ctxConfig”)”将返回该Bean。

[java] 
view plain
copy

  1. <span style=“font-size:10px;font-weight: normal;”>@Configuration(“ctxConfig”)     
  2. public class ApplicationContextConfig {     
  3.     //定义Bean配置元数据     
  4. }  </span>  


@Bean


注解配置类中的相应方法,则该方法名默认就是Bean名,该方法返回值就是Bean对象,并定义了Spring IoC容器如何实例化、自动装配、初始化Bean逻辑

[java] 
view plain
copy

  1. <span style=“font-weight: normal;”><span style=“font-size:10px;”>@Bean(name={},     
  2.       autowire=Autowire.NO,     
  3.       initMethod=“”,     
  4.       destroyMethod=“”)  </span></span>  
  • name:指定Bean的名字,可有多个,第一个作为Id,其他作为别名;
  • autowire:自动装配,默认no表示不自动装配该Bean,另外还有Autowire.BY_NAME表示根据名字自动装配,Autowire.BY_TYPE表示根据类型自动装配;
  • initMethod和destroyMethod:指定Bean的初始化和销毁方法。

@Import
类似于基于XML配置中的<import/>,基于Java的配置方式提供了@Import来组合模块化的配置类

[java] 
view plain
copy

  1. <span style=“font-size:10px;font-weight: normal;”>@Configuration(“ctxConfig2”)     
  2. @Import({ApplicationContextConfig.class})     
  3. public class ApplicationContextConfig2 {     
  4.     @Bean(name = {
    “message2”})     
  5.     public String message() {     
  6.         return “hello”;     
  7.     }     
  8. }  </span>  

JSR-250注解
@Resource 

自动装配,默认根据类型装配,如果指定name属性将根据名字装配,可以使用如下方式来指定

[java] 
view plain
copy

  1. <span style=“white-space:pre”>  </span>@Resource(name = “message”)     
  2.    <span style=“white-space:pre”>   </span>private String message;    
  • @Resource注解应该只用于setter方法注入,不能提供如@Autowired多参数方法注入;
  • @Resource在没有指定name属性的情况下首先将根据setter方法对于的字段名查找资源,如果找不到再根据类型查找;
  • @Resource首先将从JNDI环境中查找资源,如果没找到默认再到Spring容器中查找,因此如果JNDI环境中有和Spring容器同名的资源时需要注意。

@PostConstruct和PreDestroy:通过注解指定初始化和销毁方法定义;

类似于通过<bean>标签的init-method和destroy-method属性指定的初始化和销毁方法,但具有更高优先级,即注解方式的初始化和销毁方法将先执行。

• @PostConstruct
在方法上加上注解
@PostConstruct
 ,这个方法就会在
Bean
 初始化之后被
Spring
 容器执

(注:
Bean
 初始化包括,实例化
Bean
 ,并装配
Bean
 的属性(依赖注入))。

• @PreDestroy             
在方法上加上注解
@PreDestroy
 ,这个方法就会在
Bean
 被销毁前被
Spring
 容器执行。



JSR-330注解

@Inject:等价于默认的@Autowired,只是没有required属性;

@Named:指定Bean名字,对应于Spring自带@Qualifier中的缺省的根据Bean名字注入情况;

@Qualifier:只对应于Spring自带@Qualifier中的扩展@Qualifier限定描述符注解,即只能扩展使用,没有value属性。

转载于:https://my.oschina.net/zhanghaiyang/blog/606278

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100859.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 设计模式之原型(prototype)模式

    相信大多数的人都看过《西游记》,对孙悟空拔毛变出小猴子的故事情节应该都很熟悉。孙悟空可以用猴毛根据自己的形象复制出很多跟自己一模一样的小猴兵出来,其实在设计模式中也有一个类似的模式,我们可以通过一个原

    2021年12月28日
  • GEC环保创业币

    GEC环保创业币

  • 移位运算的问题「建议收藏」

    移位运算的问题「建议收藏」正数正数的原码,反码,补码相同正数,左移乘2,右移除2左移右移都补0如果左移丢1,会出错;如果右移丢1,会影响精度负数负数的原码左移补0,右移也补0左移丢1,会出错;右移丢1,会出错负数的反码左移补1,右移补1(因为原码补0不影响,那么反码应该补1)左移丢0,会出错(这里的0是原码中的1),右移丢0,会出错负数的补码从右往左的第一个1(包括这个1)往右的数和原码一样,

  • 结构体指针赋值[通俗易懂]

    结构体指针赋值[通俗易懂]//方法1:可以给p分配一段内存空间,并使其指向此空间:#includemain(){structabc{inta;};structabc*p;p=(structabc*)malloc(sizeof(structabc));p->a=1;printf(“%d\n”,p->a);}//方法2:可以让p指向一个已存在的内存空间:#i

  • FFM模型详解[通俗易懂]

    FFM模型详解[通俗易懂]FM和FFM模型是最近几年提出的模型,凭借其在数据量比较大并且特征稀疏的情况下,仍然能够得到优秀的性能和效果的特性,屡次在各大公司举办的CTR预估比赛中获得不错的战绩。美团点评技术团队在搭建DSP的过程中,探索并使用了FM和FFM模型进行CTR和CVR预估,并且取得了不错的效果。本文旨在把我们对FM和FFM原理的探索和应用的经验介绍给有兴趣的读者。文章参考:【1】文章目录1.FFM模型原理2.FFM模型实现3.FFM模型应用1.FFM模型原理假设一个广告分类的问题,根据用户和广告位相关的.

  • mfcgetdlgitem_mfc queue

    mfcgetdlgitem_mfc queueGetDlgItem 根据一个对话窗或一个控件的ID,返回一个指向这个对话窗或控件的对象的指针

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号